50 type(threefry_rng_t),
allocatable :: state(:)
52 integer,
parameter :: N_species = 3
54 type(cell_system_t) :: solvent_cells
55 type(particle_system_t) :: solvent
56 type(particle_system_t) :: colloids
57 type(neighbor_list_t) :: neigh
58 type(lj_params_t) :: solvent_colloid_lj
59 type(lj_params_t) :: colloid_lj
60 type(lj_params_t) :: walls_colloid_lj
68 integer,
parameter :: n_bins_conc = 90
69 double precision :: conc_z_cyl(n_bins_conc)
71 double precision :: sigma_N, sigma_C, max_cut, alpha, sigma_sphere
72 double precision :: shift(3)
73 double precision :: track_y_shift
74 double precision :: sigma(3,2), sigma_cut(3,2), epsilon(3,2)
75 double precision,
allocatable :: mass(:)
77 double precision :: v_com(3), wall_v(3,2), wall_t(2)
78 double precision :: local_mass, total_mass
80 double precision :: e1, e2, e_wall
81 double precision :: tau, dt , T
82 double precision :: d,prob
83 double precision :: skin, co_max, so_max
84 integer :: N_MD_steps, N_loop
85 integer :: colloid_sampling
86 integer :: n_extra_sorting
87 double precision :: kin_e, temperature
88 integer,
dimension(N_species) :: n_solvent, catalytic_change, bulk_change
89 type(h5md_element_t) :: n_solvent_el, catalytic_change_el, bulk_change_el
90 type(h5md_element_t) :: omega_el
92 double precision :: colloid_pos(3,2)
93 double precision :: com_pos(3)
94 type(h5md_file_t) :: hfile
95 type(h5md_element_t) :: dummy_element
96 integer(HID_T) :: fields_group, params_group
97 type(h5md_element_t) :: rho_xy_el
98 type(thermo_t) :: thermo_data
99 type(particle_system_io_t) :: dimer_io
100 type(particle_system_io_t) :: solvent_io
101 integer(HID_T) :: box_group
102 type(h5md_element_t) :: elem_vx, elem_vx_count
105 integer :: i, L(3), n_threads
107 integer :: i_release, i_block
109 type(timer_t),
target :: flag_timer, change_timer, buffer_timer, varia
110 type(timer_t),
target :: main
111 double precision :: total_time
112 type(timer_list_t) :: timer_list
113 integer(HID_T) :: timers_group
115 integer,
allocatable :: rho_xy(:,:,:)
117 integer,
parameter :: block_length = 8
118 type(axial_correlator_t) :: axial_cf
119 type(correlator_t) :: omega_acf
120 integer(HID_T) :: correlator_group
122 double precision :: unit_r(3), omega(3), rel_v(3), norm_xy
124 double precision :: g(3)
125 logical :: fixed, on_track, stopped, N_in_front, dimer, N_type
126 logical :: store_rho_xy
127 double precision :: store_rho_xy_z(2)
128 integer :: buffer_length
130 integer :: equilibration_loops
131 double precision :: max_speed, z, Lz
132 integer :: steps_fixed
135 args = get_input_args()
136 call ptparse(config, args%input_file, 11)
138 call flag_timer%init(
'flag')
139 call change_timer%init(
'change')
140 call buffer_timer%init(
'buffer')
141 call main%init(
'main')
142 call varia%init(
'varia')
144 call timer_list%init(14)
145 call timer_list%append(flag_timer)
146 call timer_list%append(change_timer)
147 call timer_list%append(buffer_timer)
148 call timer_list%append(varia)
150 n_threads = omp_get_max_threads()
151 allocate(state(n_threads))
152 call threefry_rng_init(state, args%seed)
156 call hfile%create(args%output_file,
'RMPCDMD::chemotactic_cell', rmpcdmd_revision,
'Pierre de Buyl')
157 call h5gcreate_f(hfile%id,
'parameters', params_group, error)
158 call hdf5_util_write_dataset(params_group,
'seed', args%seed)
161 g(1) = ptread_d(config,
'g', loc=params_group)
162 buffer_length = ptread_i(config,
'buffer_length', loc=params_group)
163 max_speed = ptread_d(config,
'max_speed', loc=params_group)
164 prob = ptread_d(config,
'probability', loc=params_group)
165 alpha = ptread_d(config,
'alpha', loc=params_group)
166 store_rho_xy = ptread_l(config,
'store_rho_xy', loc=params_group)
167 store_rho_xy_z = ptread_dvec(config,
'store_rho_xy_z', 2, loc=params_group)
168 dimer = ptread_l(config,
'dimer', loc=params_group)
169 n_type = ptread_l(config,
'N_type', loc=params_group)
175 l = ptread_ivec(config,
'L', 3, loc=params_group)
176 l(1) = l(1) + buffer_length
178 rho = ptread_i(config,
'rho', loc=params_group)
179 n = rho *l(1)*l(2)*l(3)
181 t = ptread_d(config,
'T', loc=params_group)
182 d = ptread_d(config,
'd', loc=params_group)
183 n_in_front = ptread_l(config,
'N_in_front', loc=params_group)
184 track_y_shift = ptread_d(config,
'track_y_shift', loc=params_group)
189 tau = ptread_d(config,
'tau', loc=params_group)
190 n_md_steps = ptread_i(config,
'N_MD', loc=params_group)
191 colloid_sampling = ptread_i(config,
'colloid_sampling', loc=params_group)
192 if (modulo(n_md_steps, colloid_sampling) /= 0)
then 193 error stop
'colloid_sampling must divide N_MD with no remainder' 195 dt = tau / n_md_steps
196 n_loop = ptread_i(config,
'N_loop', loc=params_group)
197 steps_fixed = ptread_i(config,
'steps_fixed', loc=params_group)
198 equilibration_loops = ptread_i(config,
'equilibration_loops', loc=params_group)
200 sigma_c = ptread_d(config,
'sigma_C', loc=params_group)
201 sigma_n = ptread_d(config,
'sigma_N', loc=params_group)
203 epsilon(:,1) = ptread_dvec(config,
'epsilon_C', n_species, loc=params_group)
204 epsilon(:,2) = ptread_dvec(config,
'epsilon_N', n_species, loc=params_group)
208 sigma_cut = sigma*2**(1.d0/6.d0)
209 max_cut = maxval(sigma_cut)
211 call solvent_colloid_lj% init(epsilon, sigma, sigma_cut)
213 sigma(1,1) = 2*sigma_c
214 sigma(1,2) = sigma_c + sigma_n
215 sigma(2,1) = sigma_c + sigma_n
216 sigma(2,2) = 2*sigma_n
217 sigma_cut = sigma*2**(1.d0/6.d0)
218 call colloid_lj% init(epsilon(1:2,:), sigma(1:2,:), sigma_cut(1:2,:))
223 sigma(2,:) = [sigma_c, sigma_n]
224 shift(2) = max(sigma_c, sigma_n)*2**(1./6.) + 0.25
225 sigma(3,:) = [sigma_c, sigma_n]
226 shift(3) = max(sigma_c, sigma_n)*2**(1./6.) + 0.25
227 sigma_cut = sigma*3**(1.d0/6.d0)
228 call walls_colloid_lj% init(epsilon(1:3,:), sigma(1:3,:), sigma_cut(1:3,:), shift)
231 sigma_sphere = sigma_n
233 sigma_sphere = sigma_c
236 allocate(mass(n_colloids))
238 mass(1) = rho * sigma_c**3 * 4 * 3.14159265/3
239 mass(2) = rho * sigma_n**3 * 4 * 3.14159265/3
241 mass = rho * sigma_sphere**3 * 4 * 3.14159265/3
244 call solvent% init(n,n_species, system_name=
'solvent')
246 call colloids% init(n_colloids,2, mass, system_name=
'colloids')
248 call thermo_data%init(hfile, n_buffer=50, step=n_md_steps, time=n_md_steps*dt)
252 call axial_cf%init(block_length, n_loop*n_md_steps/colloid_sampling, n_loop*n_md_steps)
253 call omega_acf%init(block_length, get_n_blocks(block_length, n_blocks_max=7, &
254 n_samples=n_loop*n_md_steps/colloid_sampling))
257 colloids% species(1) = 1
258 colloids% species(2) = 2
261 colloids% species = 2
263 colloids% species = 1
269 dimer_io%force_info%store = .false.
270 dimer_io%id_info%store = .false.
271 dimer_io%position_info%store = .true.
272 dimer_io%position_info%mode = ior(h5md_linear,h5md_store_time)
273 dimer_io%position_info%step = colloid_sampling
274 dimer_io%position_info%time = colloid_sampling*dt
275 dimer_io%image_info%store = .true.
276 dimer_io%image_info%mode = ior(h5md_linear,h5md_store_time)
277 dimer_io%image_info%step = colloid_sampling
278 dimer_io%image_info%time = colloid_sampling*dt
279 dimer_io%velocity_info%store = .true.
280 dimer_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
281 dimer_io%velocity_info%step = colloid_sampling
282 dimer_io%velocity_info%time = colloid_sampling*dt
283 dimer_io%species_info%store = .true.
284 dimer_io%species_info%mode = h5md_fixed
285 call dimer_io%init(hfile,
'dimer', colloids)
287 solvent_io%force_info%store = .false.
288 solvent_io%id_info%store = .false.
289 solvent_io%position_info%store = .true.
290 solvent_io%position_info%mode = ior(h5md_linear,h5md_store_time)
291 solvent_io%position_info%step = n_loop*n_md_steps
292 solvent_io%position_info%time = n_loop*n_md_steps*dt
293 solvent_io%image_info%store = .true.
294 solvent_io%image_info%mode = ior(h5md_linear,h5md_store_time)
295 solvent_io%image_info%step = n_loop*n_md_steps
296 solvent_io%image_info%time = n_loop*n_md_steps*dt
297 solvent_io%velocity_info%store = .true.
298 solvent_io%velocity_info%mode = ior(h5md_linear,h5md_store_time)
299 solvent_io%velocity_info%step = n_loop*n_md_steps
300 solvent_io%velocity_info%time = n_loop*n_md_steps*dt
301 solvent_io%species_info%store = .true.
302 solvent_io%species_info%mode = ior(h5md_linear,h5md_store_time)
303 solvent_io%species_info%step = n_loop*n_md_steps
304 solvent_io%species_info%time = n_loop*n_md_steps*dt
305 call solvent_io%init(hfile,
'solvent', solvent)
309 call solvent_cells%init(l, 1.d0,has_walls = .true.)
310 call vx% init(0.d0, solvent_cells% edges(3), l(3))
312 if (store_rho_xy)
allocate(rho_xy(n_species, l(2), l(1)))
313 call h5gcreate_f(hfile%id,
'fields', fields_group, error)
314 if (store_rho_xy)
then 315 call rho_xy_el%create_time(fields_group,
'rho_xy', rho_xy, ior(h5md_linear,h5md_store_time), &
316 step=n_md_steps, time=n_md_steps*dt)
317 call h5md_write_attribute(rho_xy_el%id,
'zmin', store_rho_xy_z(1))
318 call h5md_write_attribute(rho_xy_el%id,
'zmax', store_rho_xy_z(2))
320 call elem_vx% create_time(fields_group,
'vx', vx% data, ior(h5md_time, h5md_store_time))
321 call elem_vx_count% create_time(fields_group,
'vx_count', vx% count, ior(h5md_time, h5md_store_time))
323 call h5gclose_f(fields_group, error)
325 call n_solvent_el%create_time(hfile%observables,
'n_solvent', &
326 n_solvent, ior(h5md_linear,h5md_store_time), step=n_md_steps, &
328 call catalytic_change_el%create_time(hfile%observables,
'catalytic_change', &
329 catalytic_change, ior(h5md_linear,h5md_store_time), step=n_md_steps, &
331 call bulk_change_el%create_time(hfile%observables,
'bulk_change', &
332 bulk_change, ior(h5md_linear,h5md_store_time), step=n_md_steps, &
334 call omega_el%create_time(hfile%observables,
'omega', &
335 omega(3), ior(h5md_linear,h5md_store_time), step=colloid_sampling, &
336 time=colloid_sampling*dt)
339 colloids% pos(3,:) = solvent_cells% edges(3)/2.d0
341 colloids% pos(1,1) = sigma_c*2**(1.d0/6.d0) + 1
342 colloids% pos(1,2) = colloids% pos(1,1) + d
343 colloids% pos(2,:) = solvent_cells% edges(2)/2.d0 + track_y_shift
345 colloids% pos(1,2) = sigma_n*2**(1.d0/6.d0) + 1
346 colloids% pos(1,1) = colloids% pos(1,2) + d
347 colloids% pos(2,:) = solvent_cells% edges(2)/2.d0 + track_y_shift
350 colloids% pos(3,:) = solvent_cells% edges(3)/2.d0
351 colloids% pos(2,:) = solvent_cells% edges(2)/2.d0 + track_y_shift
352 colloids% pos(1,:) = sigma_sphere*2**(1.d0/6.d0) + 1
355 call h5gcreate_f(dimer_io%group,
'box', box_group, error)
356 call h5md_write_attribute(box_group,
'dimension', 3)
357 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
358 call h5gclose_f(box_group, error)
360 call h5gcreate_f(solvent_io%group,
'box', box_group, error)
361 call h5md_write_attribute(box_group,
'dimension', 3)
362 call dummy_element%create_fixed(box_group,
'edges', solvent_cells%edges)
363 call h5gclose_f(box_group, error)
365 call solvent% random_placement(solvent_cells% edges, colloids, solvent_colloid_lj, state(1))
367 lz = solvent_cells%edges(3)
368 do i=1, solvent% Nmax
370 solvent% vel(1,i) = threefry_normal(state(1))*sqrt(t) + &
371 max_speed*z*(lz-z)/(lz/2)**2
372 solvent% vel(2,i) = threefry_normal(state(1))*sqrt(t)
373 solvent% vel(3,i) = threefry_normal(state(1))*sqrt(t)
376 do m = 1, solvent% Nmax
377 if (solvent% pos(2,m) < (l(2)/2.d0))
then 378 solvent% species(m) = 1
380 solvent% species(m) = 3
384 call solvent% sort(solvent_cells)
386 call neigh% init(colloids% Nmax, 10*int(300*max(sigma_c,sigma_n)**3))
391 call neigh% make_stencil(solvent_cells, max_cut+skin)
393 call neigh% update_list(colloids, solvent, max_cut+skin, solvent_cells)
395 solvent% force(2:3,:) = 0
396 solvent% force(1,:) = g(1)
397 e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
398 e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
399 e_wall = lj93_zwall(colloids, solvent_cells% edges, walls_colloid_lj)
400 solvent% force_old = solvent% force
401 colloids% force_old = colloids% force
405 if (buffer_length>0)
then 414 if (buffer_length > 0)
then 415 solvent_cells%bc = [periodic_bc, specular_bc, bounce_back_bc]
417 solvent_cells%bc = [periodic_bc, periodic_bc, bounce_back_bc]
418 walls_colloid_lj%sigma(2,:) = -1
425 write(*,*)
'Running for', n_loop,
'loops' 428 setup:
do while (.not. stopped)
429 if (modulo(i,20) == 0)
write(*,
'(i09)',advance=
'no') i
430 md_loop:
do j = 1, n_md_steps
431 call mpcd_stream_xforce_yzwall(solvent, solvent_cells, dt, g(1))
433 colloids% pos_rattle = colloids% pos
435 do k=1, colloids% Nmax
436 colloids% pos(:,k) = colloids% pos(:,k) + dt * colloids% vel(:,k) + &
437 dt**2 * colloids% force(:,k) / (2 * colloids% mass(k))
441 call rattle_dimer_pos(colloids, d, dt, solvent_cells% edges)
444 if ((.not. on_track) .and. (buffer_length/=0))
then 445 do k=1, colloids% Nmax
446 if (colloids% pos(1,k) > solvent_cells% edges(1))
then 452 so_max = solvent% maximum_displacement()
453 co_max = colloids% maximum_displacement()
455 if ( (co_max >= skin*0.1) .or. (so_max >= skin*0.9) )
then 456 call apply_pbc(colloids, solvent_cells% edges)
457 call apply_pbc(solvent, solvent_cells% edges)
458 call solvent% sort(solvent_cells)
459 call neigh% update_list(colloids, solvent, max_cut + skin, solvent_cells)
462 do k = 1, solvent%Nmax
463 solvent% pos_old(:,k) = solvent% pos(:,k)
465 colloids% pos_old = colloids% pos
467 n_extra_sorting = n_extra_sorting + 1
472 call switch(solvent% force, solvent% force_old)
473 call switch(colloids% force, colloids% force_old)
476 do k = 1, solvent%Nmax
477 solvent%force(:,k) = g
480 e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
481 e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
482 if (.not. on_track)
then 483 e_wall = lj93_zwall(colloids, solvent_cells% edges, walls_colloid_lj)
486 colloids% force(2,:) = 0
487 colloids% force(3,:) = 0
489 colloids% force(1,:) = 0
493 call md_vel(solvent, dt)
495 do k=1, colloids% Nmax
496 colloids% vel(:,k) = colloids% vel(:,k) + &
497 dt * ( colloids% force(:,k) + colloids% force_old(:,k) ) / (2 * colloids% mass(k))
500 call rattle_dimer_vel(colloids, d, dt, solvent_cells% edges)
505 if ((.not. n_type) .or. (dimer))
then 506 if (.not. on_track)
then 513 com_pos = (colloids%pos(:,1)+colloids%image(:,1)*solvent_cells%edges + &
514 colloids%pos(:,2)+colloids%image(:,2)*solvent_cells%edges) / 2
515 unit_r = rel_pos(colloids%pos(:,1), colloids%pos(:,2), solvent_cells%edges)
516 norm_xy = norm2(unit_r(1:2))
517 rel_v = colloids%vel(:,1)-colloids%vel(:,2)
518 omega = cross(unit_r, rel_v) / norm_xy**2
519 unit_r = unit_r / norm2(unit_r)
522 v_com = sum(colloids%vel, dim=2)/2
523 call axial_cf%add_fast((i-i_release)*n_md_steps+j-1, v_com, unit_r)
526 if ((sampling) .and. (modulo(j, colloid_sampling)==0))
then 528 call axial_cf%add(i_block, com_pos, unit_r)
529 call omega_acf%add(i_block, correlate_block_dot, x=omega(3))
530 i_block = i_block + 1
532 call dimer_io%position%append(colloids%pos)
533 call dimer_io%velocity%append(colloids%vel)
534 call dimer_io%image%append(colloids%image)
535 call omega_el%append(omega(3))
540 call solvent_cells%random_shift(state(1))
542 call apply_pbc(colloids, solvent_cells% edges)
543 call apply_pbc(solvent, solvent_cells% edges)
544 call solvent% sort(solvent_cells)
545 call neigh% update_list(colloids, solvent, max_cut+skin, solvent_cells)
546 solvent% pos_old = solvent% pos
547 colloids% pos_old = colloids% pos
549 call wall_mpcd_step(solvent, solvent_cells, state, &
550 wall_temperature=wall_t, wall_v=wall_v, wall_n=[rho, rho], alpha=alpha)
552 call compute_vx(solvent, vx)
553 if ((sampling) .and. (modulo(i-i_release+1, 50) == 0))
then 555 call elem_vx% append(vx% data, i-i_release+1, (i-i_release+1)*tau)
556 call elem_vx_count% append(vx% count, i-i_release+1, (i-i_release+1)*tau)
561 if ((sampling) .and. (store_rho_xy))
then 563 call rho_xy_el%append(rho_xy)
567 temperature = compute_temperature(solvent, solvent_cells)
569 kin_e = sum(solvent% vel**2)/2
570 v_com = sum(solvent% vel, dim=2)
571 do k = 1, colloids% Nmax
572 m = colloids%species(k)
574 local_mass = colloids%mass(m)
575 kin_e = kin_e + local_mass*sum(colloids% vel(:,k)**2)/2
576 v_com = v_com + local_mass*colloids%vel(:,k)
577 total_mass = total_mass + local_mass
579 v_com = v_com / (solvent%Nmax + total_mass)
582 do k = 1, solvent%Nmax
583 m = solvent%species(k)
585 n_solvent(m) = n_solvent(m) + 1
589 call thermo_data%append(hfile, temperature, e1+e2+e_wall, kin_e, e1+e2+e_wall+kin_e, v_com)
590 call n_solvent_el%append(n_solvent)
591 call catalytic_change_el%append(catalytic_change)
592 call bulk_change_el%append(bulk_change)
595 call h5fflush_f(hfile%id, h5f_scope_global_f, error)
598 if (i >= steps_fixed)
then 599 write(*,*)
'fixed', fixed
606 if ((colloids% pos(1,1) > (buffer_length+sigma_c)) &
607 .and. (colloids% pos(1,2) > (buffer_length+sigma_n)))
then 611 if (colloids% pos(1,1) > (buffer_length+sigma_sphere))
then 619 ((.not. sampling) .and. (buffer_length == 0) .and. (i >= equilibration_loops)) .or. &
620 ((i_release==0) .and. (buffer_length > 0) .and. (.not. fixed)) )
then 623 write(*,*)
'i_release =', i_release
625 if (i-i_release > n_loop)
exit setup
629 call thermo_data%append(hfile, temperature, e1+e2+e_wall, kin_e, e1+e2+e_wall+kin_e, v_com, add=.false., force=.true.)
631 write(*,*)
'n extra sorting', n_extra_sorting
635 call h5gcreate_f(hfile%id,
'block_correlators', correlator_group, error)
637 call axial_cf%write(correlator_group, colloid_sampling, colloid_sampling*dt, 1, dt)
639 call write_correlator_block(correlator_group,
'planar_angular_velocity_autocorrelation', &
640 omega_acf, colloid_sampling, colloid_sampling*dt)
642 call h5gclose_f(correlator_group, error)
644 call solvent_io%position%append(solvent%pos)
645 call solvent_io%velocity%append(solvent%vel)
646 call solvent_io%image%append(solvent%image)
647 call solvent_io%species%append(solvent%species)
649 call h5gcreate_f(hfile%id,
'timers', timers_group, error)
650 call timer_list%append(solvent%time_stream)
651 call timer_list%append(solvent%time_md_vel)
652 call timer_list%append(solvent%time_step)
653 call timer_list%append(solvent%time_count)
654 call timer_list%append(solvent%time_sort)
655 call timer_list%append(solvent%time_ct)
656 call timer_list%append(solvent%time_max_disp)
657 call timer_list%append(solvent%time_apply_pbc)
658 call timer_list%append(neigh%time_update)
659 call timer_list%append(neigh%time_force)
661 call timer_list%write(timers_group, total_time)
663 call h5md_write_dataset(timers_group,
'total', total_time)
664 call h5md_write_dataset(timers_group, main%name, main%total)
666 call h5gclose_f(timers_group, error)
668 if (store_rho_xy)
call rho_xy_el%close()
669 call elem_vx% close()
670 call elem_vx_count% close()
671 call dimer_io%close()
673 call h5close_f(error)
678 double precision :: dist_to_C_sq
680 double precision :: x(3)
682 call flag_timer%tic()
686 if ((solvent% species(r)==1) .and. (.not. btest(solvent%flags(r), reac_bit)))
then 687 x = rel_pos(colloids% pos(:,1),solvent% pos(:,r),solvent_cells% edges)
688 dist_to_c_sq = dot_product(x, x)
689 if (dist_to_c_sq < solvent_colloid_lj%cut_sq(1,1))
then 690 solvent%flags(r) = ibset(solvent%flags(r), reac_bit)
694 call flag_timer%tac()
699 double precision :: dist_to_C_sq
700 double precision :: dist_to_N_sq
702 double precision :: x(3)
705 call change_timer%tic()
708 thread_id = omp_get_thread_num() + 1
710 do m = 1, solvent% Nmax
711 if (btest(solvent%flags(m), reac_bit))
then 713 x = rel_pos(colloids% pos(:,1), solvent% pos(:,m), solvent_cells% edges)
714 dist_to_c_sq = dot_product(x, x)
715 x = rel_pos(colloids% pos(:,2), solvent% pos(:,m), solvent_cells% edges)
716 dist_to_n_sq = dot_product(x, x)
718 (dist_to_c_sq > solvent_colloid_lj%cut_sq(1,1)) &
720 (dist_to_n_sq > solvent_colloid_lj%cut_sq(1,2)) &
723 if (threefry_double(state(thread_id)) <= prob)
then 724 solvent% species(m) = 2
725 catalytic_change(1) = catalytic_change(1) - 1
726 catalytic_change(2) = catalytic_change(2) + 1
728 solvent%flags(m) = ibclr(solvent%flags(m), reac_bit)
731 x = rel_pos(colloids% pos(:,1), solvent% pos(:,m), solvent_cells% edges)
732 dist_to_c_sq = dot_product(x, x)
733 if (dist_to_c_sq > solvent_colloid_lj%cut_sq(1,1))
then 734 if (threefry_double(state(thread_id)) <= prob)
then 735 solvent% species(m) = 2
736 catalytic_change(1) = catalytic_change(1) - 1
737 catalytic_change(2) = catalytic_change(2) + 1
739 solvent%flags(m) = ibclr(solvent%flags(m), reac_bit)
746 call change_timer%tac()
751 double precision :: dimer_orient(3),x(3),y(3),z(3)
752 double precision :: solvent_pos(3,solvent% nmax)
753 double precision :: dz,r,theta,x_pos,y_pos,z_pos
756 logical :: far_enough_from_wall
757 double precision :: range_min1(3),range_min2(3),range_max1(3),range_max2(3)
759 dz = 2.d0*d/n_bins_conc
760 dimer_orient = colloids% pos(:,2) - colloids% pos(:,1)
761 z = dimer_orient/sqrt(dot_product(dimer_orient,dimer_orient))
763 x = (/0.d0, 1.d0, -dimer_orient(2)/dimer_orient(3)/)
764 x = x/sqrt(dot_product(x,x))
765 y = (/z(2)*x(3)-z(3)*x(2),z(3)*x(1)-z(1)*x(3),z(1)*x(2)-z(2)*x(1)/)
768 range_min1 = colloids%pos(:,1) - d/2.0*z - (/0.d0,0.d0,1.d0/)*2*max_cut
769 range_min2 = colloids%pos(:,1) - d/2.0*z + (/0.d0,0.d0,1.d0/)*2*max_cut
770 range_max1 = colloids%pos(:,1) + 3.d0*d/2.0*z - (/0.d0,0.d0,1.d0/)*2*max_cut
771 range_max2 = colloids%pos(:,1) - 3.d0*d/2.0*z + (/0.d0,0.d0,1.d0/)*2*max_cut
773 if ( (range_min1(3)<solvent_cells%edges(3)).and.(range_min1(3)>0).and. &
774 (range_max1(3)<solvent_cells%edges(3)).and.(range_max1(3)>0).and. &
775 (range_min2(3)<solvent_cells%edges(3)).and.(range_min2(3)>0).and. &
776 (range_max2(3)<solvent_cells%edges(3)).and.(range_max2(3)>0) )
then 777 far_enough_from_wall = .true.
779 far_enough_from_wall = .false.
781 if (far_enough_from_wall)
then 782 do o = 1, solvent% Nmax
783 solvent_pos(:,o) = solvent% pos(:,o) - colloids% pos(:,1)
784 x_pos = dot_product(x,solvent_pos(:,o))
785 y_pos = dot_product(y, solvent_pos(:,o))
786 z_pos = dot_product(z, solvent_pos(:,o))
787 solvent_pos(:,o) = (/x_pos,y_pos,z_pos/)
789 do o = 1, solvent% Nmax
790 r = sqrt(solvent_pos(1,o)**2 + solvent_pos(2,o)**2)
791 theta = atan(solvent_pos(2,o)/solvent_pos(1,o))
793 solvent_pos(2,o) = theta
794 if ((solvent_pos(1,o) < 2*max_cut).and.(solvent_pos(3,o)<1.5d0*d).and.(solvent_pos(3,o)>-0.5d0*d))
then 795 if (solvent% species(o)==2)
then 796 check = floor((solvent_pos(3,o)+0.5d0*d)/dz)
798 conc_z_cyl(check) = conc_z_cyl(check) + 1
803 colloid_pos(3,1) = colloids% pos(3,1)
805 colloid_pos(3,2) = d + colloids% pos(3,1)
813 type(particle_system_t),
intent(inout) :: particles
814 double precision,
intent(in) :: edges(3)
818 call buffer_timer%tic()
821 do k = 1, particles% Nmax
822 s = particles% species(k)
824 if ((particles% pos(1,k) > 0) .and. (particles% pos(1,k) < buffer_length))
then 825 if (particles% pos(2,k) < edges(2)/2.d0)
then 826 bulk_change(s) = bulk_change(s) - 1
827 particles% species(k) = 1
829 bulk_change(s) = bulk_change(s) + 1
831 bulk_change(s) = bulk_change(s) - 1
832 particles% species(k) = 3
834 bulk_change(s) = bulk_change(s) + 1
838 call buffer_timer%tac()
843 integer :: i, s, ix, iy
844 double precision :: z
847 do i = 1, solvent%Nmax
848 s = solvent%species(i)
851 if ((z >= store_rho_xy_z(1)) .and. (z <= store_rho_xy_z(2)))
then 852 ix = modulo(floor(solvent%pos(1,i)/solvent_cells%a), l(1)) + 1
853 iy = modulo(floor(solvent%pos(2,i)/solvent_cells%a), l(2)) + 1
854 rho_xy(s, iy, ix) = rho_xy(s, iy, ix) + 1
subroutine flag_particles
subroutine concentration_field_cylindrical
program chemotactic_cell
Model a chemotactic experiment in a microfluidic channel.
subroutine buffer_particles(particles, edges)
subroutine change_species
subroutine compute_rho_xy