63 type(cell_system_t) :: solvent_cells
64 type(particle_system_t) :: solvent
65 type(particle_system_t) :: colloids
66 type(neighbor_list_t) :: neigh
67 type(lj_params_t) :: solvent_colloid_lj
68 type(lj_params_t) :: colloid_lj
69 type(lj_params_t) :: walls_colloid_lj
71 integer,
parameter :: N_species = 2
77 double precision :: max_cut
78 double precision :: epsilon(2,2)
79 double precision :: sigma, sigma_v(2,2), sigma_cut(2,2)
80 double precision :: mass(2)
81 double precision :: wall_sigma(3, n_species), wall_epsilon(3, n_species), wall_shift(3)
83 double precision :: e1, e2, e3, e4, e_wall
84 double precision :: tau, dt , T
85 double precision :: mpcd_alpha
86 double precision :: reaction_radius
87 double precision :: skin, co_max, so_max
88 integer :: N_MD_steps, N_loop
89 integer :: n_extra_sorting
90 double precision :: loop_i_last_sort
95 integer :: j, k, cell_idx
97 double precision :: total_time
98 type(timer_t),
target :: varia, main, time_flag, time_refuel, time_change
99 type(timer_t),
target :: so_timer
100 type(timer_t),
target :: bulk_reac_timer
101 type(timer_t),
target :: q_timer
102 type(timer_list_t) :: timer_list
103 integer(HID_T) :: timers_group
105 type(threefry_rng_t),
allocatable :: state(:)
107 type(h5md_file_t) :: hfile
108 type(h5md_file_t) :: input_data_file
109 type(h5md_element_t) :: dummy_element
110 integer(HID_T) :: fields_group, params_group
111 integer(HID_T) :: connectivity_group
112 integer(HID_T) :: box_group
113 integer(HID_T) :: tmp_id
114 integer(HID_T) :: pos_dset
115 type(thermo_t) :: thermo_data
116 double precision :: temperature, kin_e
117 double precision :: v_com(3), x(3)
118 double precision :: tmp_mass
119 type(particle_system_io_t) :: janus_io
120 type(particle_system_io_t) :: solvent_io
122 integer,
dimension(N_species) :: n_solvent
123 type(h5md_element_t) :: n_solvent_el
125 type(h5md_element_t) :: q_el, omega_body_el, janus_pos_el, janus_vel_el, u_el
126 double precision,
dimension(3) :: one_x, one_y, one_z
128 double precision :: polar_r_max
129 type(polar_fields_t) :: polar
130 type(planar_fields_t) :: planar
131 integer(HID_T) :: polar_id
132 integer(HID_T) :: planar_id
134 logical :: do_rattle, do_read_links, do_lennard_jones, do_elastic, do_quaternion, do_solvent_io
136 integer,
allocatable :: links(:,:)
137 double precision,
allocatable :: links_d(:)
138 double precision :: link_treshold
140 double precision :: dist, rattle_pos_tolerance, rattle_vel_tolerance
141 double precision :: elastic_k
142 double precision :: unit_r(3)
143 double precision :: com_pos(3)
144 double precision :: alpha, beta, z0
145 type(rigid_body_t) :: rigid_janus
146 double precision :: quaternion_treshold
147 character(len=144) :: fluid_wall
148 double precision :: delta_u
149 double precision :: catalytic_probability(n_species)
150 double precision :: bulk_rate(n_species)
152 integer,
parameter :: block_length = 8
153 type(axial_correlator_t) :: axial_cf
154 type(correlator_t) :: omega_cf
155 integer(HID_T) :: correlator_group
157 integer :: equilibration_loops
158 integer :: colloid_sampling
162 character(len=144) :: data_filename
163 character(len=144) :: links_file
164 character(len=144) :: data_group
165 logical :: attr_exists
167 args = get_input_args()
168 call ptparse(config, args%input_file, 11)
170 n_threads = omp_get_max_threads()
171 allocate(state(n_threads))
172 call threefry_rng_init(state, args%seed)
174 call main%init(
'main')
175 call varia%init(
'varia')
176 call so_timer%init(
'so_timer')
177 call time_flag%init(
'flag')
178 call time_refuel%init(
'refuel')
179 call time_change%init(
'change')
180 call bulk_reac_timer%init(
'bulk_reac')
181 call q_timer%init(
'quaternion_vv')
183 call timer_list%init(26)
184 call timer_list%append(varia)
185 call timer_list%append(so_timer)
186 call timer_list%append(time_flag)
187 call timer_list%append(time_refuel)
188 call timer_list%append(time_change)
189 call timer_list%append(bulk_reac_timer)
190 call timer_list%append(q_timer)
193 call hfile%create(args%output_file,
'RMPCDMD::single_body', &
194 rmpcdmd_revision,
'Pierre de Buyl')
195 call h5gcreate_f(hfile%id,
'parameters', params_group, error)
196 call hdf5_util_write_dataset(params_group,
'seed', args%seed)
199 catalytic_probability = ptread_dvec(config,
'probability', n_species, loc=params_group)
200 bulk_rate = ptread_dvec(config,
'bulk_rate', 2, loc=params_group)
202 l = ptread_ivec(config,
'L', 3, loc=params_group)
203 rho = ptread_i(config,
'rho', loc=params_group)
204 n = rho *l(1)*l(2)*l(3)
206 t = ptread_d(config,
'T', loc=params_group)
208 tau = ptread_d(config,
'tau', loc=params_group)
209 mpcd_alpha = ptread_d(config,
'alpha', loc=params_group)
210 n_md_steps = ptread_i(config,
'N_MD', loc=params_group)
211 colloid_sampling = ptread_i(config,
'colloid_sampling', loc=params_group)
212 do_solvent_io = ptread_l(config,
'do_solvent_io', loc=params_group)
213 if (modulo(n_md_steps, colloid_sampling) /= 0)
then 214 error stop
'colloid_sampling must divide N_MD with no remainder' 216 dt = tau / n_md_steps
217 n_loop = ptread_i(config,
'N_loop', loc=params_group)
218 equilibration_loops = ptread_i(config,
'equilibration_loops', loc=params_group)
220 call thermo_data%init(hfile, n_buffer=50, step=n_md_steps, time=n_md_steps*dt)
222 do_rattle = ptread_l(config,
'do_rattle', loc=params_group)
223 do_lennard_jones = ptread_l(config,
'do_lennard_jones', loc=params_group)
224 rattle_pos_tolerance = ptread_d(config,
'rattle_pos_tolerance', loc=params_group)
225 rattle_vel_tolerance = ptread_d(config,
'rattle_vel_tolerance', loc=params_group)
227 do_quaternion = ptread_l(config,
'do_quaternion', loc=params_group)
228 quaternion_treshold = ptread_d(config,
'quaternion_treshold', loc=params_group)
230 do_elastic = ptread_l(config,
'do_elastic', loc=params_group)
231 if (do_elastic) elastic_k = ptread_d(config,
'elastic_k', loc=params_group)
233 sigma = ptread_d(config,
'sigma_colloid', loc=params_group)
235 sigma_cut = sigma_v*2**(1.d0/6.d0)
236 mass = rho * sigma**3 * 4 * 3.14159265/3
238 epsilon = ptread_d(config,
'epsilon_colloid', loc=params_group)
240 call colloid_lj% init(epsilon, sigma_v, sigma_cut)
246 do_ywall = ptread_l(config,
'do_ywall', loc=params_group)
247 fluid_wall =
'PERIODIC' 249 wall_sigma(2,:) = ptread_d(config,
'wall_sigma', loc=params_group)
250 wall_shift(2) = ptread_d(config,
'wall_shift', loc=params_group)
251 wall_epsilon = ptread_d(config,
'wall_epsilon', loc=params_group)
252 call walls_colloid_lj% init(wall_epsilon, &
253 wall_sigma, 3.d0**(1.d0/6.d0)*wall_sigma, wall_shift)
254 fluid_wall = ptread_s(config,
'fluid_wall', loc=params_group)
258 sigma = ptread_d(config,
'sigma', loc=params_group)
260 sigma_cut = sigma_v*2**(1.d0/6.d0)
261 max_cut = maxval(sigma_cut)
263 epsilon(:,1) = ptread_dvec(config,
'epsilon_C', 2, loc=params_group)
264 epsilon(:,2) = ptread_dvec(config,
'epsilon_N', 2, loc=params_group)
266 call solvent_colloid_lj% init(epsilon, sigma_v, sigma_cut)
268 call solvent% init(n, n_species, system_name=
'solvent')
270 data_filename = ptread_s(config,
'data_filename', loc=params_group)
271 data_group = ptread_s(config,
'data_group', loc=params_group)
272 link_treshold = ptread_d(config,
'link_treshold', loc=params_group)
273 do_read_links = ptread_l(config,
'do_read_links', loc=params_group)
274 if (do_read_links) links_file = ptread_s(config,
'links_file', loc=params_group)
276 polar_r_max = ptread_d(config,
'polar_r_max', loc=params_group)
278 reaction_radius = ptread_d(config,
'reaction_radius', loc=params_group)
280 delta_u = ptread_d(config,
'delta_u', loc=params_group)
282 call h5gclose_f(params_group, error)
285 call solvent_cells%init(l, 1.d0)
287 solvent_cells%bc = periodic_bc
288 if (trim(fluid_wall) ==
'PERIODIC')
then 289 solvent_cells%bc(2) = periodic_bc
290 else if (trim(fluid_wall) ==
'SPECULAR')
then 291 solvent_cells%bc(2) = specular_bc
292 else if (trim(fluid_wall) ==
'BOUNCE_BACK')
then 293 solvent_cells%bc(2) = bounce_back_bc
295 error stop
'unknown value for parameter fluid_wall' 298 call axial_cf%init(block_length, n_loop, n_loop*n_md_steps)
300 call colloids%init_from_file(data_filename, data_group, h5md_fixed)
303 com_pos = sum(colloids%pos, dim=2) /
size(colloids%pos, dim=2)
304 do i = 1,
size(colloids%pos, dim=2)
305 colloids%pos(:,i) = colloids%pos(:,i) + (solvent_cells%edges/2 - com_pos)
308 call input_data_file%open(data_filename, h5f_acc_rdonly_f)
310 call h5aexists_by_name_f(input_data_file%particles, trim(data_group)//
'/position',
'alpha', attr_exists, error)
313 if (attr_exists)
then 314 call h5oopen_f(input_data_file%particles, trim(data_group)//
'/position', pos_dset, error)
315 call h5md_read_attribute(pos_dset,
'alpha', alpha)
316 call h5md_read_attribute(pos_dset,
'beta', beta)
317 call h5md_read_attribute(pos_dset,
'z0', z0)
318 call h5oclose_f(pos_dset, error)
321 call input_data_file%close()
328 if (do_read_links)
then 329 call read_links(links_file, i_link, links, links_d)
332 do i = 1, colloids%Nmax
333 do j = i+1, colloids%Nmax
334 x = rel_pos(colloids%pos(:,i), colloids%pos(:,j), solvent_cells%edges)
336 if (dist < link_treshold)
then 342 allocate(links(2,i_link), links_d(i_link))
345 do i = 1, colloids%Nmax
346 do j = i+1, colloids%Nmax
347 x = rel_pos(colloids%pos(:,i), colloids%pos(:,j), solvent_cells%edges)
349 if (dist < link_treshold)
then 354 links_d(i_link) = dist
360 call rigid_janus%init(colloids, 1, colloids%Nmax, solvent_cells%edges)
362 write(*,*)
'number of links:', i_link
364 janus_io%force_info%store = .true.
365 janus_io%force_info%mode = ior(h5md_linear,h5md_store_time)
366 janus_io%force_info%step = n_md_steps
367 janus_io%force_info%time = n_md_steps*dt
368 janus_io%id_info%store = .false.
369 janus_io%position_info%store = .true.
370 janus_io%position_info%mode = ior(h5md_linear,h5md_store_time)
371 janus_io%position_info%step = n_md_steps
372 janus_io%position_info%time = n_md_steps*dt
373 janus_io%image_info%store = .true.
374 janus_io%image_info%mode = ior(h5md_linear,h5md_store_time)
375 janus_io%image_info%step = n_md_steps
376 janus_io%image_info%time = n_md_steps*dt
377 janus_io%velocity_info%store = .true.
378 janus_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
379 janus_io%velocity_info%step = n_md_steps
380 janus_io%velocity_info%time = n_md_steps*dt
381 janus_io%species_info%store = .true.
382 janus_io%species_info%mode = h5md_fixed
383 call janus_io%init(hfile,
'janus', colloids)
385 if (do_solvent_io)
then 386 solvent_io%force_info%store = .false.
387 solvent_io%id_info%store = .false.
388 solvent_io%position_info%store = .true.
389 solvent_io%position_info%mode = ior(h5md_linear,h5md_store_time)
390 solvent_io%position_info%step = n_loop*n_md_steps
391 solvent_io%position_info%time = n_loop*n_md_steps*dt
392 solvent_io%image_info%store = .true.
393 solvent_io%image_info%mode = ior(h5md_linear,h5md_store_time)
394 solvent_io%image_info%step = n_loop*n_md_steps
395 solvent_io%image_info%time = n_loop*n_md_steps*dt
396 solvent_io%velocity_info%store = .true.
397 solvent_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
398 solvent_io%velocity_info%step = n_loop*n_md_steps
399 solvent_io%velocity_info%time = n_loop*n_md_steps*dt
400 solvent_io%species_info%store = .true.
401 solvent_io%species_info%mode = ior(h5md_linear,h5md_store_time)
402 solvent_io%species_info%step = n_loop*n_md_steps
403 solvent_io%species_info%time = n_loop*n_md_steps*dt
404 call solvent_io%init(hfile,
'solvent', solvent)
407 do k = 1, solvent%Nmax
408 solvent% vel(1,k) = threefry_normal(state(1))*sqrt(t)
409 solvent% vel(2,k) = threefry_normal(state(1))*sqrt(t)
410 solvent% vel(3,k) = threefry_normal(state(1))*sqrt(t)
412 solvent% vel = solvent% vel - spread(sum(solvent% vel, dim=2)/solvent% Nmax, 2, solvent% Nmax)
414 if ( (bulk_rate(1) > 0) .and. (bulk_rate(2) > 0) )
then 415 if (bulk_rate(1)>bulk_rate(2))
then 416 do i = 1, solvent%Nmax
417 if (threefry_double(state(1)) < bulk_rate(2)/(bulk_rate(1)+bulk_rate(2)))
then 418 solvent%species(i) = 1
420 solvent%species(i) = 2
424 do i = 1, solvent%Nmax
425 if (threefry_double(state(1)) < bulk_rate(1)/(bulk_rate(1)+bulk_rate(2)))
then 426 solvent%species(i) = 2
428 solvent%species(i) = 1
433 do i = 1, solvent%Nmax
434 if (threefry_double(state(1)) < 0.5d0)
then 435 solvent%species(i) = 2
437 solvent%species(i) = 1
442 call n_solvent_el%create_time(hfile%observables,
'n_solvent', &
443 n_solvent, h5md_linear, step=n_md_steps, &
446 if (do_quaternion)
then 447 call q_el%create_time(hfile%observables,
'q', &
448 rigid_janus%q, ior(h5md_linear, h5md_store_time), step=colloid_sampling, time=colloid_sampling*dt)
449 call omega_body_el%create_time(hfile%observables,
'omega_body', &
450 rigid_janus%omega_body, ior(h5md_linear, h5md_store_time), step=colloid_sampling, time=colloid_sampling*dt)
451 call omega_cf%init(block_length, get_n_blocks(block_length, 8, n_loop), dim=3)
454 call u_el%create_time(hfile%observables,
'u', &
455 unit_r, ior(h5md_linear, h5md_store_time), step=colloid_sampling, &
456 time=colloid_sampling*dt)
458 call janus_pos_el%create_time(hfile%observables,
'janus_pos', &
459 rigid_janus%pos, ior(h5md_linear, h5md_store_time), step=colloid_sampling, &
460 time=colloid_sampling*dt)
462 call janus_vel_el%create_time(hfile%observables,
'janus_vel', &
463 rigid_janus%vel, ior(h5md_linear, h5md_store_time), step=colloid_sampling, &
464 time=colloid_sampling*dt)
466 call h5gcreate_f(janus_io%group,
'box', box_group, error)
467 call h5md_write_attribute(box_group,
'dimension', 3)
468 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
469 call h5gclose_f(box_group, error)
471 if (do_solvent_io)
then 472 call h5gcreate_f(solvent_io%group,
'box', box_group, error)
473 call h5md_write_attribute(box_group,
'dimension', 3)
474 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
475 call h5gclose_f(box_group, error)
478 call h5gcreate_f(hfile%id,
'fields', fields_group, error)
480 call h5gcreate_f(hfile%id,
'connectivity', connectivity_group, error)
481 call h5md_write_dataset(connectivity_group,
'janus_links', links-1)
482 call h5dopen_f(connectivity_group,
'janus_links', tmp_id, error)
483 call h5md_write_attribute(tmp_id,
'particles_group',
'janus')
484 call h5dclose_f(tmp_id, error)
485 call h5gclose_f(connectivity_group, error)
487 call solvent% random_placement(solvent_cells% edges, colloids, solvent_colloid_lj, state(1))
489 call solvent% sort(solvent_cells)
491 call polar%init(n_species, 64, sigma, polar_r_max, 64)
492 call timer_list%append(polar%time_polar_update)
493 call planar%init(n_species, 64, -8.d0, 8.d0, 64, -8.d0, 8.d0, 1.d0)
494 call timer_list%append(planar%timer)
495 call neigh% init(colloids% Nmax, int(500*max(sigma,1.15d0)**3))
501 call neigh% make_stencil(solvent_cells, max_cut+skin)
503 call neigh% update_list(colloids, solvent, max_cut+skin, solvent_cells, solvent_colloid_lj)
505 e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
506 if (do_lennard_jones)
then 507 e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
512 e3 = elastic_network(colloids, links, links_d, elastic_k, solvent_cells%edges)
517 e_wall = lj93_zwall(colloids, solvent_cells% edges, walls_colloid_lj)
523 solvent% force_old = solvent% force
524 colloids% force_old = colloids% force
525 if (do_quaternion)
call rigid_janus%compute_force_torque(colloids)
527 write(*,*)
'Running for', equilibration_loops,
'+', n_loop,
'loops' 530 do i = 0, n_loop+equilibration_loops
531 if (i==equilibration_loops) sampling = .true.
532 if (modulo(i,32) == 0)
write(*,
'(i08)',advance=
'no') i
533 md_loop:
do j = 1, n_md_steps
534 if ((do_ywall) .and. (solvent_cells%bc(2)/=periodic_bc))
then 535 call cell_md_pos_ywall(solvent_cells, solvent, dt, md_flag=.true.)
537 call cell_md_pos(solvent_cells, solvent, dt, md_flag=.true.)
543 colloids% pos_rattle = colloids% pos
544 do k=1, colloids% Nmax
545 colloids% pos(:,k) = colloids% pos(:,k) + dt * colloids% vel(:,k) + &
546 dt**2 * colloids% force(:,k) / (2 * colloids% mass(colloids%species(k)))
550 call rattle_body_pos(colloids, links, links_d, dt, solvent_cells% edges, rattle_pos_tolerance)
552 com_pos = modulo(sum((colloids%pos(:,:)+ &
553 colloids%image(:,:)*spread(solvent_cells%edges, dim=2, ncopies=colloids%Nmax) ) &
554 , dim=2)/ colloids%Nmax, solvent_cells%edges)
556 else if (do_quaternion)
then 558 call rigid_janus%vv1(colloids, dt, quaternion_treshold, solvent_cells%edges)
559 com_pos = modulo(rigid_janus%pos, solvent_cells%edges)
563 so_max = cell_maximum_displacement(solvent_cells, solvent, delta_t=dt*(n_md_steps*i+j - loop_i_last_sort))
564 co_max = colloids% maximum_displacement()
566 if ( (co_max >= skin*0.1d0) .or. (so_max >= skin*0.9d0) )
then 567 if ((do_ywall) .and. (solvent_cells%bc(2)/=periodic_bc))
then 568 call cell_md_pos_ywall(solvent_cells, solvent, (n_md_steps*i+j - loop_i_last_sort)*dt, md_flag=.false.)
570 call cell_md_pos(solvent_cells, solvent, (n_md_steps*i+j - loop_i_last_sort)*dt, md_flag=.false.)
572 call cell_md_vel(solvent_cells, solvent, (n_md_steps*i+j - loop_i_last_sort)*dt, md_flag=.false.)
574 call apply_pbc(solvent, solvent_cells% edges)
575 call apply_pbc(colloids, solvent_cells% edges)
576 call solvent% sort(solvent_cells)
577 loop_i_last_sort = n_md_steps*i + j
578 call neigh% update_list(colloids, solvent, max_cut + skin, solvent_cells, solvent_colloid_lj)
581 do k = 1, solvent%Nmax
582 solvent% pos_old(:,k) = solvent% pos(:,k)
587 colloids% pos_old = colloids% pos
588 n_extra_sorting = n_extra_sorting + 1
593 call switch(solvent% force, solvent% force_old)
594 call switch(colloids% force, colloids% force_old)
599 do cell_idx = 1, solvent_cells%N
600 if (solvent_cells%is_md(cell_idx))
then 601 do k = solvent_cells%cell_start(cell_idx), &
602 solvent_cells%cell_start(cell_idx) + solvent_cells%cell_count(cell_idx) - 1
603 solvent%force(:,k) = 0
612 e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
613 if (do_lennard_jones) e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
614 if (do_elastic) e3 = elastic_network(colloids, links, links_d, elastic_k, solvent_cells%edges)
615 if (do_ywall) e_wall = lj93_zwall(colloids, solvent_cells% edges, walls_colloid_lj)
617 call cell_md_vel(solvent_cells, solvent, dt, md_flag=.true.)
619 if (do_quaternion)
then 621 call rigid_janus%compute_force_torque(colloids)
622 call rigid_janus%vv2(colloids, dt)
624 else if (do_rattle)
then 626 do k = 1, colloids%Nmax
627 colloids% vel(:,k) = colloids% vel(:,k) + &
628 dt * ( colloids% force(:,k) + colloids% force_old(:,k) ) / (2 * colloids%mass(colloids%species(k)))
634 call rattle_body_vel(colloids, links, links_d, dt, solvent_cells% edges, rattle_vel_tolerance)
638 v_com = sum(colloids%vel, dim=2)/colloids%Nmax
639 com_pos = sum((colloids%pos(:,:)+ &
640 colloids%image(:,:)*spread(solvent_cells%edges, dim=2, ncopies=colloids%Nmax) ) &
641 , dim=2)/ colloids%Nmax
642 if (do_rattle .and. (.not. do_quaternion))
then 643 rigid_janus%pos = com_pos
644 rigid_janus%vel = v_com
647 call axial_cf%add_fast((i-equilibration_loops)*n_md_steps+j-1, v_com, unit_r)
650 if ((sampling) .and. (modulo(j, colloid_sampling)==0))
then 651 call u_el%append(unit_r)
652 call janus_pos_el%append(rigid_janus%pos)
653 call janus_vel_el%append(rigid_janus%vel)
654 if (do_quaternion)
then 655 call q_el%append(rigid_janus%q)
656 call omega_body_el%append(rigid_janus%omega_body)
663 temperature = compute_temperature(solvent, solvent_cells)
668 do k = 1, solvent%Nmax
669 kin_e = kin_e + sum(solvent%vel(:,k)**2)
670 v_com = v_com + solvent%vel(:,k)
674 tmp_mass = solvent%Nmax
675 do k = 1, colloids%Nmax
676 v_com = v_com + colloids%mass(colloids%species(k)) * colloids%vel(:,k)
677 tmp_mass = tmp_mass + colloids%mass(colloids%species(k))
678 kin_e = kin_e + colloids%mass(colloids%species(k)) * sum(colloids%vel(:,k)**2)
680 v_com = v_com / tmp_mass
686 do k = 1, solvent%Nmax
687 j = solvent%species(k)
689 n_solvent(j) = n_solvent(j) + 1
692 e4 = n_solvent(1)*delta_u
693 call thermo_data%append(hfile, temperature, e1+e2+e3+e4+e_wall, kin_e, e1+e2+e3+e4+e_wall+kin_e, v_com)
694 call axial_cf%add(i-equilibration_loops, com_pos, unit_r)
698 call solvent_cells%random_shift(state(1))
700 call cell_md_pos(solvent_cells, solvent, ((i+1)*n_md_steps - loop_i_last_sort)*dt, md_flag=.false.)
701 call cell_md_vel(solvent_cells, solvent, ((i+1)*n_md_steps - loop_i_last_sort)*dt, md_flag=.false.)
703 call apply_pbc(solvent, solvent_cells% edges)
704 call apply_pbc(colloids, solvent_cells% edges)
705 call solvent% sort(solvent_cells)
706 loop_i_last_sort = n_md_steps*(i+1)
707 call neigh% update_list(colloids, solvent, max_cut+skin, solvent_cells, solvent_colloid_lj)
709 do k = 1, solvent%Nmax
710 solvent% pos_old(:,k) = solvent% pos(:,k)
712 colloids% pos_old = colloids% pos
714 call simple_mpcd_step(solvent, solvent_cells, state, alpha=mpcd_alpha)
717 call bulk_reac_timer%tic()
718 call bulk_reaction_endothermic(solvent, solvent_cells, 2, 1, bulk_rate(2), tau, state, delta_u)
719 call bulk_reaction_endothermic(solvent, solvent_cells, 1, 2, bulk_rate(1), tau, state, -delta_u)
720 call bulk_reac_timer%tac()
723 call n_solvent_el%append(n_solvent)
726 v_com = sum(colloids%vel, dim=2)/colloids%Nmax
728 call polar%update(com_pos, v_com, unit_r/norm2(unit_r), solvent, solvent_cells)
729 one_x = qrot(rigid_janus%q, [1.d0, 0.d0, 0.d0])
730 one_y = qrot(rigid_janus%q, [0.d0, 0.d0, 1.d0])
731 one_z = qrot(rigid_janus%q, [0.d0, -1.d0, 0.d0])
732 call planar%update(com_pos, v_com, one_x, one_y, one_z, qrot(rigid_janus%q, rigid_janus%omega_body), &
733 solvent, solvent_cells)
735 if (do_quaternion)
call omega_cf%add(i-equilibration_loops, correlate_block_dot, xvec=rigid_janus%omega_body)
737 call janus_io%position%append(colloids%pos)
738 call janus_io%force%append(colloids%force)
739 call janus_io%velocity%append(colloids%vel)
740 call janus_io%image%append(colloids%image)
747 write(*,*)
'n extra sorting', n_extra_sorting
751 call h5gcreate_f(hfile%id,
'block_correlators', correlator_group, error)
752 call axial_cf%write(correlator_group, n_md_steps, n_md_steps*dt, 1, dt)
754 call write_correlator_block(correlator_group,
'omega_body_autocorrelation', omega_cf, n_md_steps, n_md_steps*dt)
755 call h5gclose_f(correlator_group, error)
758 e4 = n_solvent(1)*delta_u
759 call thermo_data%append(hfile, temperature, e1+e2+e3+e4+e_wall, kin_e, e1+e2+e3+e4+e_wall+kin_e, v_com, add=.false., force=.true.)
760 if (do_solvent_io)
then 761 call solvent_io%position%append(solvent%pos)
762 call solvent_io%velocity%append(solvent%vel)
763 call solvent_io%image%append(solvent%image)
764 call solvent_io%species%append(solvent%species)
765 call solvent_io%close()
770 where (polar%count>0)
771 polar%v(1,:,:,:) = polar%v(1,:,:,:) / polar%count
772 polar%v(2,:,:,:) = polar%v(2,:,:,:) / polar%count
774 call h5md_write_dataset(fields_group,
'polar_concentration', dble(polar%count)/n_loop)
775 call h5oopen_f(fields_group,
'polar_concentration', polar_id, error)
776 call h5md_write_attribute(polar_id,
'r_min', polar%r_min)
777 call h5md_write_attribute(polar_id,
'r_max', polar%r_max)
778 call h5md_write_attribute(polar_id,
'dr', polar%dr)
779 call h5md_write_attribute(polar_id,
'dtheta', polar%dtheta)
780 call h5oclose_f(polar_id, error)
782 call h5md_write_dataset(fields_group,
'polar_velocity', polar%v)
783 call h5oopen_f(fields_group,
'polar_velocity', polar_id, error)
784 call h5md_write_attribute(polar_id,
'r_min', polar%r_min)
785 call h5md_write_attribute(polar_id,
'r_max', polar%r_max)
786 call h5md_write_attribute(polar_id,
'dr', polar%dr)
787 call h5md_write_attribute(polar_id,
'dtheta', polar%dtheta)
788 call h5oclose_f(polar_id, error)
792 where (planar%count>0)
793 planar%v(1,:,:,:) = planar%v(1,:,:,:) / planar%count
794 planar%v(2,:,:,:) = planar%v(2,:,:,:) / planar%count
796 call h5md_write_dataset(fields_group,
'planar_concentration', dble(planar%count)/n_loop)
797 call h5oopen_f(fields_group,
'planar_concentration', planar_id, error)
798 call h5md_write_attribute(planar_id,
'x_min', planar%x_min)
799 call h5md_write_attribute(planar_id,
'dx', planar%dx)
800 call h5md_write_attribute(planar_id,
'y_min', planar%y_min)
801 call h5md_write_attribute(planar_id,
'dy', planar%dy)
802 call h5md_write_attribute(planar_id,
'thickness', planar%thickness)
803 call h5oclose_f(planar_id, error)
805 call h5md_write_dataset(fields_group,
'planar_velocity', planar%v)
806 call h5oopen_f(fields_group,
'planar_velocity', 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)
815 call timer_list%append(solvent%time_stream)
816 call timer_list%append(solvent%time_step)
817 call timer_list%append(solvent%time_count)
818 call timer_list%append(solvent%time_sort)
819 call timer_list%append(solvent%time_ct)
820 call timer_list%append(solvent%time_md_pos)
821 call timer_list%append(solvent%time_md_vel)
822 call timer_list%append(solvent%time_max_disp)
823 call timer_list%append(solvent%time_apply_pbc)
824 call timer_list%append(colloids%time_self_force)
825 call timer_list%append(colloids%time_rattle_pos)
826 call timer_list%append(colloids%time_rattle_vel)
827 call timer_list%append(colloids%time_elastic)
828 call timer_list%append(colloids%time_apply_pbc)
829 call timer_list%append(neigh%time_update)
830 call timer_list%append(neigh%time_force)
831 call timer_list%append(colloids%time_max_disp)
833 call h5gcreate_f(hfile%id,
'timers', timers_group, error)
834 call timer_list%write(timers_group, total_time)
835 call h5md_write_dataset(timers_group,
'total', total_time)
836 call h5md_write_dataset(timers_group, main%name, main%total)
837 call h5gclose_f(timers_group, error)
839 call h5gclose_f(fields_group, error)
840 call janus_io%close()
841 call n_solvent_el%close()
842 if (do_quaternion)
then 844 call omega_body_el%close()
847 call janus_pos_el%close()
848 call janus_vel_el%close()
850 call h5close_f(error)
856 integer :: start, count
857 integer :: m, thread_id, i, flags, n_react, idx_react(30), j
858 integer :: non_md_particles
859 double precision :: xi
861 double precision :: kin_energy, com_v(3), local_excess, factor
864 thread_id = omp_get_thread_num() + 1
867 do i = 1, solvent_cells%N
868 start = solvent_cells%cell_start(i)
869 count = solvent_cells%cell_count(i)
870 if (count <= 1) cycle
875 detect_loop:
do m = start, start + count - 1
876 flags = solvent%flags(m)
877 if ( (btest(flags, md_bit)) .and. (btest(flags, catalyzed_bit)) .and. (.not. btest(flags, past_md_bit)) )
then 880 xi = threefry_double(state(thread_id))
883 if (threefry_double(state(thread_id)) < catalytic_probability(solvent%species(m)))
then 884 n_react = n_react + 1
885 idx_react(n_react) = m
889 solvent%flags(m) = ibset(flags, outbound_bit)
891 solvent%flags(m) = ibclr(flags, catalyzed_bit)
892 else if (.not. (btest(flags, md_bit)) .and. (btest(flags, past_md_bit)) )
then 895 if (btest(flags, outbound_bit))
then 896 if (threefry_double(state(thread_id)) < catalytic_probability(solvent%species(m)))
then 897 n_react = n_react + 1
898 idx_react(n_react) = m
902 if (.not. btest(solvent%flags(m), md_bit))
then 903 non_md_particles = non_md_particles + 1
904 com_v = com_v + solvent%vel(:,m)
908 if (non_md_particles <= 1) cycle
909 com_v = com_v / non_md_particles
912 do m = start, start + count - 1
913 if (.not. btest(solvent%flags(m), md_bit))
then 914 kin_energy = kin_energy + sum((solvent%vel(:,m)-com_v)**2)/2
918 if (n_react > 0)
then 923 local_excess = local_excess + (3-2*solvent%species(m))*delta_u
926 if (kin_energy + local_excess > 0)
then 929 solvent%species(m) = 3 - solvent%species(m)
932 factor = sqrt((kin_energy + local_excess)/kin_energy)
933 do m = start, start + count - 1
934 if (.not. btest(solvent%flags(m), md_bit))
then 935 solvent%vel(:,m) = com_v + factor*(solvent%vel(:,m)-com_v)
948 subroutine read_links(filename, n_links, links, links_d)
949 character(len=*),
intent(in) :: filename
950 integer,
intent(out) :: n_links
951 integer,
allocatable,
intent(out) :: links(:,:)
952 double precision,
allocatable,
intent(out) :: links_d(:)
956 double precision :: l
959 open(11, file=filename)
960 count_loop:
do while (.true.)
961 read(11, *, iostat=iostat) i1, i2, l
962 if (iostat.lt.0)
exit count_loop
963 n_links = n_links + 1
967 allocate(links(2, n_links), links_d(n_links))
968 open(11, file=filename)
970 read(11, *, iostat=iostat) i1, i2, l
980 double precision :: u_r(3)
981 double precision :: r1(3), r2(3), r3(3)
982 double precision,
parameter :: one_z(3) = [0.d0, 0.d0, 1.d0]
984 if (do_quaternion)
then 985 u_r = qrot(rigid_janus%q, one_z)
986 else if (attr_exists)
then 987 r1 = rel_pos(colloids%pos(:,1), com_pos, solvent_cells%edges)
988 r2 = rel_pos(colloids%pos(:,2), com_pos, solvent_cells%edges)
989 r3 = rel_pos(colloids%pos(:,3), com_pos, solvent_cells%edges)
990 u_r = (r1 + alpha*r2 + beta*r3) / z0
999 double precision :: local_max_v
1003 do i = 1, solvent_cells%N
1005 do j = solvent_cells%cell_start(i), solvent_cells%cell_start(i) + solvent_cells%cell_count(i) - 1
1006 local_max_v = max(local_max_v, norm2(solvent%vel(:,j)))
1009 solvent_cells%max_v = local_max_v
double precision function, dimension(3) get_unit_r()
subroutine read_links(filename, n_links, links, links_d)
subroutine detect_reaction
subroutine compute_cell_wise_max_v
program single_body_thermal
Simulate a single colloidal rigid-body particle.