29 integer,
parameter :: N_species = 2
35 double precision :: epsilon, sigma, sigma_cut
36 double precision :: mass
38 double precision :: e1
39 double precision :: tau, dt , T
40 double precision :: prob
41 double precision :: skin, so_max
42 integer :: N_MD_steps, N_loop
43 integer :: n_extra_sorting
50 type(
timer_t) :: time_flag, time_refuel, time_change
51 type(threefry_rng_t),
allocatable :: state(:)
53 type(h5md_file_t) :: hfile
54 type(h5md_element_t) :: dummy_element
55 integer(HID_T) :: fields_group
56 integer(HID_T) :: box_group
58 double precision :: temperature, kin_e
59 double precision :: v_com(3)
62 integer,
dimension(N_species) :: n_solvent
63 type(h5md_element_t) :: n_solvent_el
66 type(h5md_element_t) :: polar_hist_el
68 logical :: rmpcd_refuel
69 double precision :: bulk_rate
73 n_threads = omp_get_max_threads()
74 allocate(state(n_threads))
75 call threefry_rng_init(state, ptread_c_int64(config,
'seed'))
77 call main%init(
'main')
78 call varia%init(
'varia')
79 call time_flag%init(
'flag')
80 call time_refuel%init(
'refuel')
81 call time_change%init(
'change')
85 prob = ptread_d(config,
'probability')
86 rmpcd_refuel = ptread_l(config,
'rmpcd_refuel')
87 bulk_rate = ptread_d(config,
'bulk_rate')
89 l = ptread_ivec(config,
'L', 3)
90 rho = ptread_i(config,
'rho')
91 n = rho *l(1)*l(2)*l(3)
93 t = ptread_d(config,
'T')
95 tau = ptread_d(config,
'tau')
96 n_md_steps = ptread_i(config,
'N_MD')
98 n_loop = ptread_i(config,
'N_loop')
100 epsilon = ptread_d(config,
'epsilon')
101 sigma = ptread_d(config,
'sigma')
102 sigma_cut = sigma*2**(1.d0/6.d0)
103 mass = rho * sigma**3 * 4 * 3.14159265/3
105 call solvent_colloid_lj% init(&
106 reshape([epsilon, epsilon], [2, 1]),&
107 reshape([sigma, sigma], [2, 1]),&
108 reshape([sigma_cut, sigma_cut], [2, 1]))
110 call solvent% init(n,2)
112 call colloids% init(1,1, [mass])
114 call hfile%create(ptread_s(config,
'h5md_file'), &
115 'RMPCDMD::setup_single_catalytic_fixed_sphere',
'N/A',
'Pierre de Buyl')
116 call thermo_data%init(hfile, n_buffer=50, step=n_md_steps, time=n_md_steps*dt)
120 colloids% species(1) = 1
123 solvent_io%force_info%store = .false.
124 solvent_io%id_info%store = .false.
125 solvent_io%position_info%store = .true.
126 solvent_io%position_info%mode = ior(h5md_linear,h5md_store_time)
127 solvent_io%position_info%step = n_loop*n_md_steps
128 solvent_io%position_info%time = n_loop*n_md_steps*dt
129 solvent_io%image_info%store = .true.
130 solvent_io%image_info%mode = ior(h5md_linear,h5md_store_time)
131 solvent_io%image_info%step = n_loop*n_md_steps
132 solvent_io%image_info%time = n_loop*n_md_steps*dt
133 solvent_io%velocity_info%store = .true.
134 solvent_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
135 solvent_io%velocity_info%step = n_loop*n_md_steps
136 solvent_io%velocity_info%time = n_loop*n_md_steps*dt
137 solvent_io%species_info%store = .true.
138 solvent_io%species_info%mode = ior(h5md_linear,h5md_store_time)
139 solvent_io%species_info%step = n_loop*n_md_steps
140 solvent_io%species_info%time = n_loop*n_md_steps*dt
141 call solvent_io%init(hfile,
'solvent', solvent)
143 call random_number(solvent% vel(:, :))
144 solvent% vel = (solvent% vel - 0.5d0)*sqrt(12*t)
145 solvent% vel = solvent% vel - spread(sum(solvent% vel,
dim=2)/solvent% Nmax, 2, solvent% Nmax)
149 call solvent_cells%init(l, 1.d0)
150 colloids% pos(:,1) = solvent_cells% edges/2.0
152 call n_solvent_el%create_time(hfile%observables,
'n_solvent', &
153 n_solvent, h5md_linear, step=n_md_steps, &
156 call h5gcreate_f(solvent_io%group,
'box', box_group, error)
157 call h5md_write_attribute(box_group,
'dimension', 3)
158 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
159 call h5gclose_f(box_group, error)
161 call h5gcreate_f(hfile%id,
'fields', fields_group, error)
162 call polar_hist%init(0.d0, 3*sigma, 100, 2)
163 call polar_hist_el%create_time(fields_group,
'polar_histogram', polar_hist%data, &
164 h5md_linear, step=n_md_steps, time=n_md_steps*dt)
165 call h5md_write_attribute(polar_hist_el%id,
'xmin', polar_hist%xmin)
166 call h5md_write_attribute(polar_hist_el%id,
'dx', polar_hist%dx)
167 call h5gclose_f(fields_group, error)
169 call solvent% random_placement(solvent_cells% edges, colloids, solvent_colloid_lj, state(1))
171 call solvent% sort(solvent_cells)
173 call neigh% init(colloids% Nmax, int(300*sigma**3))
178 call neigh% make_stencil(solvent_cells, sigma_cut+skin)
180 call neigh% update_list(colloids, solvent, sigma_cut+skin, solvent_cells)
182 e1 =
compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
183 solvent% force_old = solvent% force
184 colloids% force_old = colloids% force
186 write(*,*)
'Running for', n_loop,
'loops' 189 if (modulo(i,5) == 0)
write(*,
'(i05)',advance=
'no') i
190 md_loop:
do j = 1, n_md_steps
193 so_max = solvent% maximum_displacement()
195 if ( so_max >= skin )
then 197 call apply_pbc(solvent, solvent_cells% edges)
199 call solvent% sort(solvent_cells)
200 call neigh% update_list(colloids, solvent, sigma_cut + skin, solvent_cells)
202 solvent% pos_old = solvent% pos
203 n_extra_sorting = n_extra_sorting + 1
208 call switch(solvent% force, solvent% force_old)
209 call switch(colloids% force, colloids% force_old)
212 do k = 1, solvent%Nmax
213 solvent% force(:,k) = 0
217 e1 =
compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
224 call time_change%tic()
226 call time_change%tac()
233 kin_e = sum(solvent% vel**2)/2
234 v_com = sum(solvent% vel,
dim=2) / solvent%Nmax
236 call thermo_data%append(hfile, temperature, e1, kin_e, e1+kin_e, v_com)
238 solvent_cells% origin(1) = threefry_double(state(1)) - 1
239 solvent_cells% origin(2) = threefry_double(state(1)) - 1
240 solvent_cells% origin(3) = threefry_double(state(1)) - 1
243 call solvent% sort(solvent_cells)
244 call neigh% update_list(colloids, solvent, sigma_cut+skin, solvent_cells)
249 call time_refuel%tic()
250 if (rmpcd_refuel)
then 251 call bulk_reaction(solvent, solvent_cells, 2, 1, bulk_rate, tau, state)
255 call time_refuel%tac()
258 do k = 1, solvent%Nmax
259 j = solvent%species(k)
261 n_solvent(j) = n_solvent(j) + 1
263 call n_solvent_el%append(n_solvent)
271 write(*,*)
'n extra sorting', n_extra_sorting
273 call solvent_io%position%append(solvent%pos)
274 call solvent_io%velocity%append(solvent%vel)
275 call solvent_io%image%append(solvent%image)
276 call solvent_io%species%append(solvent%species)
278 call solvent_io%close()
279 call n_solvent_el%close()
281 call h5close_f(error)
283 write(*,
'(a16,f8.3)') solvent%time_stream%name, solvent%time_stream%total
284 write(*,
'(a16,f8.3)') solvent%time_step%name, solvent%time_step%total
285 write(*,
'(a16,f8.3)') solvent%time_count%name, solvent%time_count%total
286 write(*,
'(a16,f8.3)') solvent%time_sort%name, solvent%time_sort%total
287 write(*,
'(a16,f8.3)') solvent%time_ct%name, solvent%time_ct%total
288 write(*,
'(a16,f8.3)') solvent%time_md_pos%name, solvent%time_md_pos%total
289 write(*,
'(a16,f8.3)') solvent%time_md_vel%name, solvent%time_md_vel%total
290 write(*,
'(a16,f8.3)') solvent%time_max_disp%name, solvent%time_max_disp%total
291 write(*,
'(a16,f8.3)') colloids%time_self_force%name, solvent%time_self_force%total
292 write(*,
'(a16,f8.3)') neigh%time_update%name, neigh%time_update%total
293 write(*,
'(a16,f8.3)') neigh%time_force%name, neigh%time_force%total
294 write(*,
'(a16,f8.3)') colloids%time_max_disp%name, colloids%time_max_disp%total
295 write(*,
'(a16,f8.3)') time_flag%name, time_flag%total
296 write(*,
'(a16,f8.3)') time_change%name, time_change%total
297 write(*,
'(a16,f8.3)') time_refuel%name, time_refuel%total
299 write(*,
'(a16,f8.3)')
'total', solvent%time_stream%total + solvent%time_step%total + &
300 solvent%time_count%total + solvent%time_sort%total + solvent%time_ct%total + &
301 solvent%time_md_pos%total + solvent%time_md_vel%total + &
302 solvent%time_max_disp%total + solvent%time_self_force%total + &
303 neigh%time_update%total + neigh%time_force%total + colloids%time_max_disp%total + &
304 time_flag%total + time_change%total + time_refuel%total
306 write(*,
'(a16,f8.3)') varia%name, varia%total
307 write(*,
'(a16,f8.3)') main%name, main%total
312 double precision :: dist_to_C_sq
314 double precision :: x(3)
318 if (solvent% species(r) == 1)
then 319 x =
rel_pos(colloids% pos(:,1),solvent% pos(:,r),solvent_cells% edges)
320 dist_to_c_sq = dot_product(x, x)
321 if (dist_to_c_sq < solvent_colloid_lj%cut_sq(1,1))
then 322 if (threefry_double(state(1)) <= prob)
then 323 solvent%flags(r) = ibset(solvent%flags(r),
reac_bit)
332 double precision :: dist_to_sphere_sq
334 double precision :: x(3)
337 do m = 1, solvent% Nmax
338 if (btest(solvent%flags(m),
reac_bit))
then 339 x =
rel_pos(colloids% pos(:,1), solvent% pos(:,m), solvent_cells% edges)
340 dist_to_sphere_sq = dot_product(x, x)
341 if (dist_to_sphere_sq > solvent_colloid_lj%cut_sq(1,1))
then 342 solvent% species(m) = 2
343 solvent%flags(m) = ibclr(solvent%flags(m),
reac_bit)
351 double precision :: dist_to_C_sq
352 double precision :: dist_to_N_sq
353 double precision :: far
354 double precision :: x(3)
360 do n = 1,solvent% Nmax
361 if (solvent% species(n) == 2)
then 362 x =
rel_pos(colloids% pos(:,1), solvent% pos(:,n), solvent_cells% edges)
363 dist_to_c_sq = dot_product(x, x)
364 x=
rel_pos(colloids% pos(:,2), solvent% pos(:,n), solvent_cells% edges)
365 dist_to_n_sq = dot_product(x, x)
366 if ((dist_to_c_sq > far) .and. (dist_to_n_sq > far))
then 367 solvent% species(n) = 1
375 double precision :: r, x(3), r_up
378 do i = 1, solvent%Nmax
379 s = solvent%species(i)
381 x =
rel_pos(colloids% pos(:,1), solvent% pos(:,i), solvent_cells% edges)
383 call polar_hist%bin(r, s)
386 do i = 1, polar_hist%n
387 r = (i-1)*polar_hist%dx
388 r_up = i*polar_hist%dx
389 polar_hist%data(:,i) = polar_hist%data(:,i) / (4.d0/3.d0*
pi*(r_up**3-r**3))
392 call polar_hist_el%append(polar_hist%data)
Derived type and routines for neighbor listing.
subroutine, public md_vel(particles, dt)
character(len=max_path_length) function, public get_input_filename()
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.
subroutine, public bulk_reaction(p, c, from, to, rate, tau, state)
Apply a bulk unimolecular RMPCD reaction.
double precision function, public compute_force(ps1, ps2, n_list, L, lj_params)
subroutine change_species
subroutine, public apply_pbc(particles, edges)
Compute compact Hilbert indices.
integer, parameter, public reac_bit
subroutine update_polar_hist
subroutine flag_particles_nl
Facilities for particle data I/O.
subroutine, public md_pos(particles, dt)
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.
Container for a histogram, e.g. p(x)
Lennard-Jones potential definition.
double precision, parameter, public pi
program setup_single_catalytic_fixed_sphere