68 type(cell_system_t) :: solvent_cells
69 type(particle_system_t) :: solvent
70 type(particle_system_t) :: colloids
71 type(neighbor_list_t) :: neigh
72 type(lj_params_t) :: solvent_colloid_lj
73 type(lj_params_t) :: colloid_lj
74 type(lj_params_t) :: walls_colloid_lj
76 integer,
parameter :: N_species = 2
82 double precision :: max_cut
83 double precision :: epsilon(2,2)
84 double precision :: sigma, sigma_v(2,2), sigma_cut(2,2)
85 double precision :: mass(2)
86 double precision :: wall_sigma(3, n_species), wall_epsilon(3, n_species), wall_shift(3)
88 double precision :: e1, e2, e3, e_wall
89 double precision :: tau, dt , T
90 double precision :: mpcd_alpha
91 double precision :: prob, reaction_radius
92 double precision :: bulk_rate
93 double precision :: skin, co_max, so_max
94 integer :: N_MD_steps, N_loop, collide_every
95 integer :: n_extra_sorting
96 double precision :: loop_i_last_sort
101 integer :: j, k, cell_idx
103 double precision :: total_time
104 type(timer_t),
target :: varia, main, time_flag, time_refuel, time_change
105 type(timer_t),
target :: so_timer
106 type(timer_t),
target :: bulk_reac_timer
107 type(timer_t),
target :: q_timer
108 type(timer_list_t) :: timer_list
109 integer(HID_T) :: timers_group
111 type(threefry_rng_t),
allocatable :: state(:)
113 type(h5md_file_t) :: hfile
114 type(h5md_file_t) :: input_data_file
115 type(h5md_element_t) :: dummy_element
116 integer(HID_T) :: fields_group, params_group
117 integer(HID_T) :: connectivity_group
118 integer(HID_T) :: box_group
119 integer(HID_T) :: tmp_id
120 integer(HID_T) :: pos_dset
121 type(thermo_t) :: thermo_data
122 double precision :: temperature, kin_e
123 double precision :: v_com(3), x(3)
124 double precision :: wall_v(3,2)
125 double precision :: tmp_mass
126 type(particle_system_io_t) :: janus_io
127 type(particle_system_io_t) :: solvent_io
129 integer,
dimension(N_species) :: n_solvent
130 type(h5md_element_t) :: n_solvent_el
132 type(h5md_element_t) :: q_el, omega_body_el, janus_pos_el, janus_vel_el, u_el
133 double precision,
dimension(3) :: one_x, one_y, one_z
135 double precision :: polar_r_max
136 type(polar_fields_t) :: polar
137 type(planar_fields_t) :: planar
138 integer :: planar_n(2)
139 double precision :: planar_size(2)
140 integer(HID_T) :: polar_id
141 integer(HID_T) :: planar_id
143 logical :: do_rattle, do_read_links, do_lennard_jones, do_elastic, do_quaternion, do_solvent_io
145 logical :: do_thermostat
147 integer,
allocatable :: links(:,:)
148 double precision,
allocatable :: links_d(:)
149 double precision :: link_treshold
151 double precision :: dist, rattle_pos_tolerance, rattle_vel_tolerance
152 double precision :: elastic_k
153 double precision :: unit_r(3)
154 double precision :: com_pos(3)
155 double precision :: alpha, beta, z0
156 type(rigid_body_t) :: rigid_janus
157 double precision :: quaternion_treshold
158 character(len=144) :: fluid_wall
160 integer,
parameter :: block_length = 8
161 type(axial_correlator_t) :: axial_cf
162 type(correlator_t) :: omega_cf
163 integer(HID_T) :: correlator_group
165 integer :: equilibration_loops
166 integer :: colloid_sampling, coordinates_sampling
168 logical :: collision_step
171 character(len=144) :: data_filename
172 character(len=144) :: links_file
173 character(len=144) :: data_group
174 logical :: attr_exists
176 args = get_input_args()
177 call ptparse(config, args%input_file, 11)
179 n_threads = omp_get_max_threads()
180 allocate(state(n_threads))
181 call threefry_rng_init(state, args%seed)
183 call main%init(
'main')
184 call varia%init(
'varia')
185 call so_timer%init(
'so_timer')
186 call time_flag%init(
'flag')
187 call time_refuel%init(
'refuel')
188 call time_change%init(
'change')
189 call bulk_reac_timer%init(
'bulk_reac')
190 call q_timer%init(
'quaternion_vv')
192 call timer_list%init(26)
193 call timer_list%append(varia)
194 call timer_list%append(so_timer)
195 call timer_list%append(time_flag)
196 call timer_list%append(time_refuel)
197 call timer_list%append(time_change)
198 call timer_list%append(bulk_reac_timer)
199 call timer_list%append(q_timer)
202 call hfile%create(args%output_file,
'RMPCDMD::single_body', &
203 rmpcdmd_revision,
'Pierre de Buyl')
204 call h5gcreate_f(hfile%id,
'parameters', params_group, error)
205 call hdf5_util_write_dataset(params_group,
'seed', args%seed)
208 prob = ptread_d(config,
'probability', loc=params_group)
209 bulk_rate = ptread_d(config,
'bulk_rate', loc=params_group)
211 l = ptread_ivec(config,
'L', 3, loc=params_group)
212 rho = ptread_i(config,
'rho', loc=params_group)
213 n = rho *l(1)*l(2)*l(3)
215 t = ptread_d(config,
'T', loc=params_group)
216 do_hydro = ptread_l(config,
'do_hydro', loc=params_group)
217 do_thermostat = ptread_l(config,
'do_thermostat', loc=params_group)
219 mpcd_alpha = ptread_d(config,
'alpha', loc=params_group)
221 dt = ptread_d(config,
'dt', loc=params_group)
222 n_md_steps = ptread_i(config,
'N_MD', loc=params_group)
224 collide_every = ptread_i(config,
'collide_every', loc=params_group)
225 tau = dt*n_md_steps*collide_every
226 call hdf5_util_write_dataset(params_group,
'tau', tau)
228 colloid_sampling = ptread_i(config,
'colloid_sampling', loc=params_group)
229 coordinates_sampling = ptread_i(config,
'coordinates_sampling', loc=params_group)
230 do_solvent_io = ptread_l(config,
'do_solvent_io', loc=params_group)
231 if (modulo(n_md_steps, colloid_sampling) /= 0)
then 232 error stop
'colloid_sampling must divide N_MD with no remainder' 234 n_loop = ptread_i(config,
'N_loop', loc=params_group)
235 equilibration_loops = ptread_i(config,
'equilibration_loops', loc=params_group)
237 call thermo_data%init(hfile, n_buffer=50, step=n_md_steps, time=n_md_steps*dt)
239 do_rattle = ptread_l(config,
'do_rattle', loc=params_group)
240 do_lennard_jones = ptread_l(config,
'do_lennard_jones', loc=params_group)
241 rattle_pos_tolerance = ptread_d(config,
'rattle_pos_tolerance', loc=params_group)
242 rattle_vel_tolerance = ptread_d(config,
'rattle_vel_tolerance', loc=params_group)
244 do_quaternion = ptread_l(config,
'do_quaternion', loc=params_group)
245 quaternion_treshold = ptread_d(config,
'quaternion_treshold', loc=params_group)
247 do_elastic = ptread_l(config,
'do_elastic', loc=params_group)
248 if (do_elastic) elastic_k = ptread_d(config,
'elastic_k', loc=params_group)
250 sigma = ptread_d(config,
'sigma_colloid', loc=params_group)
252 sigma_cut = sigma_v*2**(1.d0/6.d0)
253 mass = rho * sigma**3 * 4 * 3.14159265/3
255 epsilon = ptread_d(config,
'epsilon_colloid', loc=params_group)
257 call colloid_lj% init(epsilon, sigma_v, sigma_cut)
263 do_ywall = ptread_l(config,
'do_ywall', loc=params_group)
264 fluid_wall =
'PERIODIC' 266 wall_sigma(3,:) = ptread_d(config,
'wall_sigma', loc=params_group)
267 wall_shift(3) = ptread_d(config,
'wall_shift', loc=params_group)
268 wall_epsilon = ptread_d(config,
'wall_epsilon', loc=params_group)
269 call walls_colloid_lj% init(wall_epsilon, &
270 wall_sigma, 3.d0**(1.d0/6.d0)*wall_sigma, wall_shift)
271 fluid_wall = ptread_s(config,
'fluid_wall', loc=params_group)
275 sigma = ptread_d(config,
'sigma', loc=params_group)
277 sigma_cut = sigma_v*2**(1.d0/6.d0)
278 max_cut = maxval(sigma_cut)
280 epsilon(:,1) = ptread_dvec(config,
'epsilon_C', 2, loc=params_group)
281 epsilon(:,2) = ptread_dvec(config,
'epsilon_N', 2, loc=params_group)
283 call solvent_colloid_lj% init(epsilon, sigma_v, sigma_cut)
285 call solvent% init(n, n_species, system_name=
'solvent')
287 data_filename = ptread_s(config,
'data_filename', loc=params_group)
288 data_group = ptread_s(config,
'data_group', loc=params_group)
289 link_treshold = ptread_d(config,
'link_treshold', loc=params_group)
290 do_read_links = ptread_l(config,
'do_read_links', loc=params_group)
291 if (do_read_links) links_file = ptread_s(config,
'links_file', loc=params_group)
293 polar_r_max = ptread_d(config,
'polar_r_max', loc=params_group)
295 reaction_radius = ptread_d(config,
'reaction_radius', loc=params_group)
297 planar_n = ptread_ivec(config,
'planar_n', 2, loc=params_group)
298 planar_size = ptread_dvec(config,
'planar_size', 2, loc=params_group)
299 call planar%init(n_species, planar_n(1), -planar_size(1), planar_size(1), planar_n(2), -planar_size(2), planar_size(2), 1.d0)
301 call h5gclose_f(params_group, error)
304 call solvent_cells%init(l, 1.d0, &
305 has_walls= ( (trim(fluid_wall) ==
'SPECULAR') &
306 .or. (trim(fluid_wall) ==
'BOUNCE_BACK')) )
309 solvent_cells%bc = periodic_bc
310 if (trim(fluid_wall) ==
'PERIODIC')
then 311 solvent_cells%bc(3) = periodic_bc
312 else if (trim(fluid_wall) ==
'SPECULAR')
then 313 solvent_cells%bc(3) = specular_bc
314 else if (trim(fluid_wall) ==
'BOUNCE_BACK')
then 315 solvent_cells%bc(3) = bounce_back_bc
317 error stop
'unknown value for parameter fluid_wall' 320 call axial_cf%init(block_length, n_loop, n_loop*n_md_steps)
322 call colloids%init_from_file(data_filename, data_group, h5md_fixed)
325 com_pos = sum(colloids%pos, dim=2) /
size(colloids%pos, dim=2)
326 do i = 1,
size(colloids%pos, dim=2)
327 colloids%pos(:,i) = colloids%pos(:,i) + (solvent_cells%edges/2 - com_pos)
330 call input_data_file%open(data_filename, h5f_acc_rdonly_f)
332 call h5aexists_by_name_f(input_data_file%particles, trim(data_group)//
'/position',
'alpha', attr_exists, error)
335 if (attr_exists)
then 336 call h5oopen_f(input_data_file%particles, trim(data_group)//
'/position', pos_dset, error)
337 call h5md_read_attribute(pos_dset,
'alpha', alpha)
338 call h5md_read_attribute(pos_dset,
'beta', beta)
339 call h5md_read_attribute(pos_dset,
'z0', z0)
340 call h5oclose_f(pos_dset, error)
343 call input_data_file%close()
350 if (do_read_links)
then 351 call read_links(links_file, i_link, links, links_d)
354 do i = 1, colloids%Nmax
355 do j = i+1, colloids%Nmax
356 x = rel_pos(colloids%pos(:,i), colloids%pos(:,j), solvent_cells%edges)
358 if (dist < link_treshold)
then 364 allocate(links(2,i_link), links_d(i_link))
367 do i = 1, colloids%Nmax
368 do j = i+1, colloids%Nmax
369 x = rel_pos(colloids%pos(:,i), colloids%pos(:,j), solvent_cells%edges)
371 if (dist < link_treshold)
then 376 links_d(i_link) = dist
382 call rigid_janus%init(colloids, 1, colloids%Nmax, solvent_cells%edges)
384 write(*,*)
'number of links:', i_link
386 janus_io%force_info%store = .true.
387 janus_io%force_info%mode = ior(h5md_linear,h5md_store_time)
388 janus_io%force_info%step = n_md_steps*coordinates_sampling
389 janus_io%force_info%time = n_md_steps*coordinates_sampling*dt
390 janus_io%id_info%store = .false.
391 janus_io%position_info%store = .true.
392 janus_io%position_info%mode = ior(h5md_linear,h5md_store_time)
393 janus_io%position_info%step = janus_io%force_info%step
394 janus_io%position_info%time = janus_io%force_info%time
395 janus_io%image_info%store = .true.
396 janus_io%image_info%mode = ior(h5md_linear,h5md_store_time)
397 janus_io%image_info%step = janus_io%force_info%step
398 janus_io%image_info%time = janus_io%force_info%time
399 janus_io%velocity_info%store = .true.
400 janus_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
401 janus_io%velocity_info%step = janus_io%force_info%step
402 janus_io%velocity_info%time = janus_io%force_info%time
403 janus_io%species_info%store = .true.
404 janus_io%species_info%mode = h5md_fixed
405 call janus_io%init(hfile,
'janus', colloids)
407 if (do_solvent_io)
then 408 solvent_io%force_info%store = .false.
409 solvent_io%id_info%store = .false.
410 solvent_io%position_info%store = .true.
411 solvent_io%position_info%mode = ior(h5md_linear,h5md_store_time)
412 solvent_io%position_info%step = n_loop*n_md_steps
413 solvent_io%position_info%time = n_loop*n_md_steps*dt
414 solvent_io%image_info%store = .true.
415 solvent_io%image_info%mode = ior(h5md_linear,h5md_store_time)
416 solvent_io%image_info%step = n_loop*n_md_steps
417 solvent_io%image_info%time = n_loop*n_md_steps*dt
418 solvent_io%velocity_info%store = .true.
419 solvent_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
420 solvent_io%velocity_info%step = n_loop*n_md_steps
421 solvent_io%velocity_info%time = n_loop*n_md_steps*dt
422 solvent_io%species_info%store = .true.
423 solvent_io%species_info%mode = ior(h5md_linear,h5md_store_time)
424 solvent_io%species_info%step = n_loop*n_md_steps
425 solvent_io%species_info%time = n_loop*n_md_steps*dt
426 call solvent_io%init(hfile,
'solvent', solvent)
429 do k = 1, solvent%Nmax
430 solvent% vel(1,k) = threefry_normal(state(1))*sqrt(t)
431 solvent% vel(2,k) = threefry_normal(state(1))*sqrt(t)
432 solvent% vel(3,k) = threefry_normal(state(1))*sqrt(t)
434 solvent% vel = solvent% vel - spread(sum(solvent% vel, dim=2)/solvent% Nmax, 2, solvent% Nmax)
438 call n_solvent_el%create_time(hfile%observables,
'n_solvent', &
439 n_solvent, h5md_linear, step=n_md_steps, &
442 if (do_quaternion)
then 443 call q_el%create_time(hfile%observables,
'q', &
444 rigid_janus%q, ior(h5md_linear, h5md_store_time), step=colloid_sampling, time=colloid_sampling*dt)
445 call omega_body_el%create_time(hfile%observables,
'omega_body', &
446 rigid_janus%omega_body, ior(h5md_linear, h5md_store_time), step=colloid_sampling, time=colloid_sampling*dt)
447 call omega_cf%init(block_length, get_n_blocks(block_length, 8, n_loop), dim=3)
450 call u_el%create_time(hfile%observables,
'u', &
451 unit_r, ior(h5md_linear, h5md_store_time), step=colloid_sampling, &
452 time=colloid_sampling*dt)
454 call janus_pos_el%create_time(hfile%observables,
'janus_pos', &
455 rigid_janus%pos, ior(h5md_linear, h5md_store_time), step=colloid_sampling, &
456 time=colloid_sampling*dt)
458 call janus_vel_el%create_time(hfile%observables,
'janus_vel', &
459 rigid_janus%vel, ior(h5md_linear, h5md_store_time), step=colloid_sampling, &
460 time=colloid_sampling*dt)
462 call h5gcreate_f(janus_io%group,
'box', box_group, error)
463 call h5md_write_attribute(box_group,
'dimension', 3)
464 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
465 call h5gclose_f(box_group, error)
467 if (do_solvent_io)
then 468 call h5gcreate_f(solvent_io%group,
'box', box_group, error)
469 call h5md_write_attribute(box_group,
'dimension', 3)
470 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
471 call h5gclose_f(box_group, error)
474 call h5gcreate_f(hfile%id,
'fields', fields_group, error)
476 call h5gcreate_f(hfile%id,
'connectivity', connectivity_group, error)
477 call h5md_write_dataset(connectivity_group,
'janus_links', links-1)
478 call h5dopen_f(connectivity_group,
'janus_links', tmp_id, error)
479 call h5md_write_attribute(tmp_id,
'particles_group',
'janus')
480 call h5dclose_f(tmp_id, error)
481 call h5gclose_f(connectivity_group, error)
483 call solvent% random_placement(solvent_cells% edges, colloids, solvent_colloid_lj, state(1))
485 call solvent% sort(solvent_cells)
487 call polar%init(n_species, 64, sigma, polar_r_max, 64)
488 call timer_list%append(polar%time_polar_update)
489 call timer_list%append(planar%timer)
490 call neigh% init(colloids% Nmax, int(500*max(sigma,1.15d0)**3))
496 call neigh% make_stencil(solvent_cells, max_cut+skin)
498 call neigh% update_list(colloids, solvent, max_cut+skin, solvent_cells, solvent_colloid_lj)
500 e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
501 if (do_lennard_jones)
then 502 e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
507 e3 = elastic_network(colloids, links, links_d, elastic_k, solvent_cells%edges)
512 e_wall = lj93_zwall(colloids, solvent_cells% edges, walls_colloid_lj)
517 solvent% force_old = solvent% force
518 colloids% force_old = colloids% force
519 if (do_quaternion)
call rigid_janus%compute_force_torque(colloids)
521 write(*,*)
'Box size', l
522 write(*,*)
'Fluid particles', n
523 write(*,*)
'MPCD tau', tau
525 write(*,*)
'Running for', equilibration_loops,
'+', n_loop,
'loops' 528 do i = 0, n_loop+equilibration_loops
529 if (i==equilibration_loops) sampling = .true.
530 if (modulo(i,32) == 0)
write(*,
'(i08)',advance=
'no') i
531 md_loop:
do j = 1, n_md_steps
532 if ((do_ywall) .and. (solvent_cells%bc(3)/=periodic_bc))
then 533 call cell_md_pos_zwall(solvent_cells, solvent, dt, md_flag=.true.)
535 call cell_md_pos(solvent_cells, solvent, dt, md_flag=.true.)
541 colloids% pos_rattle = colloids% pos
542 do k=1, colloids% Nmax
543 colloids% pos(:,k) = colloids% pos(:,k) + dt * colloids% vel(:,k) + &
544 dt**2 * colloids% force(:,k) / (2 * colloids% mass(colloids%species(k)))
548 call rattle_body_pos(colloids, links, links_d, dt, solvent_cells% edges, rattle_pos_tolerance)
550 com_pos = modulo(sum((colloids%pos(:,:)+ &
551 colloids%image(:,:)*spread(solvent_cells%edges, dim=2, ncopies=colloids%Nmax) ) &
552 , dim=2)/ colloids%Nmax, solvent_cells%edges)
554 else if (do_quaternion)
then 556 call rigid_janus%vv1(colloids, dt, quaternion_treshold, solvent_cells%edges)
557 com_pos = modulo(rigid_janus%pos, solvent_cells%edges)
561 so_max = cell_maximum_displacement(solvent_cells, solvent, delta_t=dt*(n_md_steps*i+j - loop_i_last_sort))
562 co_max = colloids% maximum_displacement()
564 if ( (co_max >= skin*0.1d0) .or. (so_max >= skin*0.9d0) )
then 565 if ((do_ywall) .and. (solvent_cells%bc(3)/=periodic_bc))
then 566 call cell_md_pos_zwall(solvent_cells, solvent, (n_md_steps*i+j - loop_i_last_sort)*dt, md_flag=.false.)
568 call cell_md_pos(solvent_cells, solvent, (n_md_steps*i+j - loop_i_last_sort)*dt, md_flag=.false.)
570 call cell_md_vel(solvent_cells, solvent, (n_md_steps*i+j - loop_i_last_sort)*dt, md_flag=.false.)
572 call apply_pbc(solvent, solvent_cells% edges)
573 call apply_pbc(colloids, solvent_cells% edges)
574 call solvent% sort(solvent_cells)
575 loop_i_last_sort = n_md_steps*i + j
576 call neigh% update_list(colloids, solvent, max_cut + skin, solvent_cells, solvent_colloid_lj)
579 do k = 1, solvent%Nmax
580 solvent% pos_old(:,k) = solvent% pos(:,k)
585 colloids% pos_old = colloids% pos
586 n_extra_sorting = n_extra_sorting + 1
591 call switch(solvent% force, solvent% force_old)
592 call switch(colloids% force, colloids% force_old)
597 do cell_idx = 1, solvent_cells%N
598 if (solvent_cells%is_md(cell_idx))
then 599 do k = solvent_cells%cell_start(cell_idx), &
600 solvent_cells%cell_start(cell_idx) + solvent_cells%cell_count(cell_idx) - 1
601 solvent%force(:,k) = 0
608 e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
609 if (do_lennard_jones) e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
610 if (do_elastic) e3 = elastic_network(colloids, links, links_d, elastic_k, solvent_cells%edges)
611 if (do_ywall) e_wall = lj93_zwall(colloids, solvent_cells% edges, walls_colloid_lj)
613 call cell_md_vel(solvent_cells, solvent, dt, md_flag=.true.)
615 if (do_quaternion)
then 617 call rigid_janus%compute_force_torque(colloids)
618 call rigid_janus%vv2(colloids, dt)
620 else if (do_rattle)
then 622 do k = 1, colloids%Nmax
623 colloids% vel(:,k) = colloids% vel(:,k) + &
624 dt * ( colloids% force(:,k) + colloids% force_old(:,k) ) / (2 * colloids%mass(colloids%species(k)))
630 call rattle_body_vel(colloids, links, links_d, dt, solvent_cells% edges, rattle_vel_tolerance)
634 v_com = sum(colloids%vel, dim=2)/colloids%Nmax
635 com_pos = sum((colloids%pos(:,:)+ &
636 colloids%image(:,:)*spread(solvent_cells%edges, dim=2, ncopies=colloids%Nmax) ) &
637 , dim=2)/ colloids%Nmax
638 if (do_rattle .and. (.not. do_quaternion))
then 639 rigid_janus%pos = com_pos
640 rigid_janus%vel = v_com
643 call axial_cf%add_fast((i-equilibration_loops)*n_md_steps+j-1, v_com, unit_r)
646 if ((sampling) .and. (modulo(j, colloid_sampling)==0))
then 647 call u_el%append(unit_r)
648 call janus_pos_el%append(rigid_janus%pos)
649 call janus_vel_el%append(rigid_janus%vel)
650 if (do_quaternion)
then 651 call q_el%append(rigid_janus%q)
652 call omega_body_el%append(rigid_janus%omega_body)
659 call time_change%tic()
661 call time_change%tac()
665 collision_step = (modulo(i, collide_every) == 0)
668 temperature = compute_temperature(solvent, solvent_cells)
673 do k = 1, solvent%Nmax
674 kin_e = kin_e + sum(solvent%vel(:,k)**2)
675 v_com = v_com + solvent%vel(:,k)
679 tmp_mass = solvent%Nmax
680 do k = 1, colloids%Nmax
681 v_com = v_com + colloids%mass(colloids%species(k)) * colloids%vel(:,k)
682 tmp_mass = tmp_mass + colloids%mass(colloids%species(k))
683 kin_e = kin_e + colloids%mass(colloids%species(k)) * sum(colloids%vel(:,k)**2)
685 v_com = v_com / tmp_mass
688 call thermo_data%append(hfile, temperature, e1+e2+e3+e_wall, kin_e, e1+e2+e3+e_wall+kin_e, v_com)
689 call axial_cf%add(i-equilibration_loops, com_pos, unit_r)
693 if (collision_step)
call solvent_cells%random_shift(state(1))
695 call cell_md_pos(solvent_cells, solvent, ((i+1)*n_md_steps - loop_i_last_sort)*dt, md_flag=.false.)
696 call cell_md_vel(solvent_cells, solvent, ((i+1)*n_md_steps - loop_i_last_sort)*dt, md_flag=.false.)
698 call apply_pbc(solvent, solvent_cells% edges)
699 call apply_pbc(colloids, solvent_cells% edges)
700 call solvent% sort(solvent_cells)
701 loop_i_last_sort = n_md_steps*(i+1)
702 call neigh% update_list(colloids, solvent, max_cut+skin, solvent_cells, solvent_colloid_lj)
704 do k = 1, solvent%Nmax
705 solvent% pos_old(:,k) = solvent% pos(:,k)
707 colloids% pos_old = colloids% pos
709 if (collision_step)
call wall_mpcd_step(solvent, solvent_cells, state, &
710 wall_temperature=[t, t], wall_v=wall_v, wall_n=[rho, rho], &
711 alpha=mpcd_alpha, keep_cell_v=do_hydro, thermostat=do_thermostat, &
715 call bulk_reac_timer%tic()
716 call bulk_reaction(solvent, solvent_cells, 2, 1, bulk_rate, n_md_steps*dt, state)
717 call bulk_reac_timer%tac()
723 do k = 1, solvent%Nmax
724 j = solvent%species(k)
726 n_solvent(j) = n_solvent(j) + 1
729 call n_solvent_el%append(n_solvent)
732 v_com = sum(colloids%vel, dim=2)/colloids%Nmax
734 call polar%update(com_pos, v_com, unit_r/norm2(unit_r), solvent, solvent_cells)
735 one_x = qrot(rigid_janus%q, [1.d0, 0.d0, 0.d0])
736 one_y = qrot(rigid_janus%q, [0.d0, 1.d0, 0.d0])
737 one_z = qrot(rigid_janus%q, [0.d0, 0.d0, 1.d0])
738 com_pos = modulo(com_pos, solvent_cells%edges)
739 call planar%update(com_pos, v_com, one_x, one_y, one_z, qrot(rigid_janus%q, rigid_janus%omega_body), &
740 solvent, solvent_cells)
742 if (do_quaternion)
call omega_cf%add(i-equilibration_loops, correlate_block_dot, xvec=rigid_janus%omega_body)
744 if ((i > equilibration_loops) .and. (modulo(i-equilibration_loops, coordinates_sampling)==0))
then 745 call janus_io%position%append(colloids%pos)
746 call janus_io%force%append(colloids%force)
747 call janus_io%velocity%append(colloids%vel)
748 call janus_io%image%append(colloids%image)
756 write(*,*)
'n extra sorting', n_extra_sorting
760 call h5gcreate_f(hfile%id,
'block_correlators', correlator_group, error)
761 call axial_cf%write(correlator_group, n_md_steps, n_md_steps*dt, 1, dt)
763 call write_correlator_block(correlator_group,
'omega_body_autocorrelation', omega_cf, n_md_steps, n_md_steps*dt)
764 call h5gclose_f(correlator_group, error)
768 call thermo_data%append(hfile, temperature, e1+e2+e3+e_wall, kin_e, e1+e2+e3+e_wall+kin_e, v_com, add=.false., force=.true.)
769 if (do_solvent_io)
then 770 call solvent_io%position%append(solvent%pos)
771 call solvent_io%velocity%append(solvent%vel)
772 call solvent_io%image%append(solvent%image)
773 call solvent_io%species%append(solvent%species)
774 call solvent_io%close()
779 where (polar%count>0)
780 polar%v(1,:,:,:) = polar%v(1,:,:,:) / polar%count
781 polar%v(2,:,:,:) = polar%v(2,:,:,:) / polar%count
783 call h5md_write_dataset(fields_group,
'polar_concentration', dble(polar%count)/n_loop)
784 call h5oopen_f(fields_group,
'polar_concentration', polar_id, error)
785 call h5md_write_attribute(polar_id,
'r_min', polar%r_min)
786 call h5md_write_attribute(polar_id,
'r_max', polar%r_max)
787 call h5md_write_attribute(polar_id,
'dr', polar%dr)
788 call h5md_write_attribute(polar_id,
'dtheta', polar%dtheta)
789 call h5oclose_f(polar_id, error)
791 call h5md_write_dataset(fields_group,
'polar_velocity', polar%v)
792 call h5oopen_f(fields_group,
'polar_velocity', polar_id, error)
793 call h5md_write_attribute(polar_id,
'r_min', polar%r_min)
794 call h5md_write_attribute(polar_id,
'r_max', polar%r_max)
795 call h5md_write_attribute(polar_id,
'dr', polar%dr)
796 call h5md_write_attribute(polar_id,
'dtheta', polar%dtheta)
797 call h5oclose_f(polar_id, error)
801 where (planar%count>0)
802 planar%v(1,:,:,:) = planar%v(1,:,:,:) / planar%count
803 planar%v(2,:,:,:) = planar%v(2,:,:,:) / planar%count
805 call h5md_write_dataset(fields_group,
'planar_concentration', planar%count/n_loop)
806 call h5oopen_f(fields_group,
'planar_concentration', planar_id, error)
807 call h5md_write_attribute(planar_id,
'x_min', planar%x_min)
808 call h5md_write_attribute(planar_id,
'dx', planar%dx)
809 call h5md_write_attribute(planar_id,
'y_min', planar%y_min)
810 call h5md_write_attribute(planar_id,
'dy', planar%dy)
811 call h5md_write_attribute(planar_id,
'thickness', planar%thickness)
812 call h5oclose_f(planar_id, error)
814 call h5md_write_dataset(fields_group,
'planar_velocity', planar%v)
815 call h5oopen_f(fields_group,
'planar_velocity', planar_id, error)
816 call h5md_write_attribute(planar_id,
'x_min', planar%x_min)
817 call h5md_write_attribute(planar_id,
'dx', planar%dx)
818 call h5md_write_attribute(planar_id,
'y_min', planar%y_min)
819 call h5md_write_attribute(planar_id,
'dy', planar%dy)
820 call h5md_write_attribute(planar_id,
'thickness', planar%thickness)
821 call h5oclose_f(planar_id, error)
824 call timer_list%append(solvent%time_stream)
825 call timer_list%append(solvent%time_step)
826 call timer_list%append(solvent%time_count)
827 call timer_list%append(solvent%time_sort)
828 call timer_list%append(solvent%time_ct)
829 call timer_list%append(solvent%time_md_pos)
830 call timer_list%append(solvent%time_md_vel)
831 call timer_list%append(solvent%time_max_disp)
832 call timer_list%append(solvent%time_apply_pbc)
833 call timer_list%append(colloids%time_self_force)
834 call timer_list%append(colloids%time_rattle_pos)
835 call timer_list%append(colloids%time_rattle_vel)
836 call timer_list%append(colloids%time_elastic)
837 call timer_list%append(colloids%time_apply_pbc)
838 call timer_list%append(neigh%time_update)
839 call timer_list%append(neigh%time_force)
840 call timer_list%append(colloids%time_max_disp)
842 call h5gcreate_f(hfile%id,
'timers', timers_group, error)
843 call timer_list%write(timers_group, total_time)
844 call h5md_write_dataset(timers_group,
'total', total_time)
845 call h5md_write_dataset(timers_group, main%name, main%total)
846 call h5gclose_f(timers_group, error)
848 call h5gclose_f(fields_group, error)
849 call janus_io%close()
850 call n_solvent_el%close()
851 if (do_quaternion)
then 853 call omega_body_el%close()
856 call janus_pos_el%close()
857 call janus_vel_el%close()
859 call h5close_f(error)
864 double precision :: dist_to_C_sq
866 double precision :: x(3)
870 do i = 1, colloids%Nmax
871 if (colloids%species(i)==1)
then 874 if (solvent% species(r) == 1)
then 875 x = rel_pos(colloids% pos(:,i),solvent% pos(:,r),solvent_cells% edges)
876 dist_to_c_sq = dot_product(x, x)
877 if (dist_to_c_sq < solvent_colloid_lj%cut_sq(1,1))
then 879 solvent%flags(r) = ior(solvent%flags(r), reac_mask)
891 integer :: m, thread_id, i
892 double precision :: dist
895 thread_id = omp_get_thread_num() + 1
897 do i = 1, solvent_cells%N
898 change_loop:
do m = solvent_cells%cell_start(i), solvent_cells%cell_start(i) + solvent_cells%cell_count(i) - 1
899 if (solvent%species(m) /= 1) cycle change_loop
900 if ((btest(solvent%flags(m), reac_bit)) .and. (.not. btest(solvent%flags(m), md_bit)))
then 901 dist = norm2(rel_pos(modulo(rigid_janus%pos, solvent_cells%edges), solvent%pos(:,m), solvent_cells%edges))
902 if (dist > reaction_radius)
then 903 if (threefry_double(state(thread_id)) < prob) solvent%species(m) = 2
904 solvent%flags(m) = ibclr(solvent%flags(m), reac_bit)
915 double precision :: dist_to_C_sq
916 double precision :: dist_to_N_sq
917 double precision :: far
918 double precision :: x(3)
924 do n = 1,solvent% Nmax
925 if (solvent% species(n) == 2)
then 926 x = rel_pos(colloids% pos(:,1), solvent% pos(:,n), solvent_cells% edges)
927 dist_to_c_sq = dot_product(x, x)
928 x= rel_pos(colloids% pos(:,2), solvent% pos(:,n), solvent_cells% edges)
929 dist_to_n_sq = dot_product(x, x)
930 if ((dist_to_c_sq > far) .and. (dist_to_n_sq > far))
then 931 solvent% species(n) = 1
937 subroutine read_links(filename, n_links, links, links_d)
938 character(len=*),
intent(in) :: filename
939 integer,
intent(out) :: n_links
940 integer,
allocatable,
intent(out) :: links(:,:)
941 double precision,
allocatable,
intent(out) :: links_d(:)
945 double precision :: l
948 open(11, file=filename)
949 count_loop:
do while (.true.)
950 read(11, *, iostat=iostat) i1, i2, l
951 if (iostat.lt.0)
exit count_loop
952 n_links = n_links + 1
956 allocate(links(2, n_links), links_d(n_links))
957 open(11, file=filename)
959 read(11, *, iostat=iostat) i1, i2, l
969 double precision :: u_r(3)
970 double precision :: r1(3), r2(3), r3(3)
971 double precision,
parameter :: one_y(3) = [0.d0, 1.d0, 0.d0]
973 if (do_quaternion)
then 974 u_r = qrot(rigid_janus%q, one_y)
975 else if (attr_exists)
then 976 r1 = rel_pos(colloids%pos(:,1), com_pos, solvent_cells%edges)
977 r2 = rel_pos(colloids%pos(:,2), com_pos, solvent_cells%edges)
978 r3 = rel_pos(colloids%pos(:,3), com_pos, solvent_cells%edges)
979 u_r = (r1 + alpha*r2 + beta*r3) / z0
988 double precision :: local_max_v
992 do i = 1, solvent_cells%N
994 do j = solvent_cells%cell_start(i), solvent_cells%cell_start(i) + solvent_cells%cell_count(i) - 1
995 local_max_v = max(local_max_v, norm2(solvent%vel(:,j)))
998 solvent_cells%max_v = local_max_v
double precision function, dimension(3) get_unit_r()
program single_body
Simulate a single colloidal rigid-body particle.
subroutine flag_particles
subroutine change_species
subroutine read_links(filename, n_links, links, links_d)
subroutine compute_cell_wise_max_v