22 double precision :: edges(3)
25 double precision :: origin(3)
26 integer,
allocatable :: cell_count(:)
27 integer,
allocatable :: cell_count_tmp(:,:)
28 integer,
allocatable :: cell_start(:)
29 logical,
allocatable :: is_md(:)
30 logical,
allocatable :: is_reac(:)
31 double precision :: max_v
37 procedure :: count_particles
38 procedure :: sort_particles
39 procedure :: random_shift
40 procedure :: cartesian_indices
49 subroutine init(this, L, a, has_walls)
52 integer,
intent(in) :: L(3)
53 double precision,
intent(in) :: a
54 logical,
intent(in),
optional :: has_walls
60 if (
present(has_walls))
then 61 this% has_walls = has_walls
63 this% has_walls = .false.
65 if (this% has_walls)
then 73 do while ( 2**this%M(i) < l(i) )
74 this%M(i) = this%M(i)+1
77 this%N = 2**this%M(1)*2**this%M(2)*2**this%M(3)
78 allocate(this%cell_count(this%N))
79 allocate(this%cell_count_tmp(this%N, omp_get_max_threads()))
80 allocate(this%cell_start(this%N))
81 allocate(this%is_md(this%N))
82 allocate(this%is_reac(this%N))
89 double precision,
intent(in) :: position(:, :)
91 integer :: i, idx, N_particles, thread_max
97 n_particles =
size(position, 2)
98 thread_max = omp_get_max_threads()
101 nowalls = .not. this% has_walls
103 this%cell_count_tmp = 0
106 thread_id = omp_get_thread_num() + 1
109 p = this%cartesian_indices(position(:,i))
111 this%cell_count_tmp(idx, thread_id) = this%cell_count_tmp(idx, thread_id) + 1
118 this%cell_count(i) = 0
119 do thread_id=1, thread_max
120 this%cell_count(i) = this%cell_count(i) + this%cell_count_tmp(i, thread_id)
124 this%cell_start(1) = 1
126 this%cell_start(i) = this%cell_start(i-1) + this%cell_count(i-1)
133 double precision,
intent(in) :: position_old(:, :)
134 double precision,
intent(out) :: position_new(:, :)
136 integer :: i, idx, N, start, p(3)
138 n =
size(position_old, 2)
142 p = this%cartesian_indices(position_old(:,i))
145 start = this%cell_start(idx)
146 this%cell_start(idx) = this%cell_start(idx) + 1
148 position_new(:, start) = position_old(:, i)
157 type(threefry_rng_t),
intent(inout) :: state
159 this%origin(1) = threefry_double(state) - 1
160 this%origin(2) = threefry_double(state) - 1
161 this%origin(3) = threefry_double(state) - 1
167 double precision,
intent(in) :: position(3)
170 p = floor( (position / this%a) - this%origin )
171 if (p(1) == this%L(1)) p(1) = 0
172 if (p(2) == this%L(2)) p(2) = 0
173 if ( (.not. this%has_walls) .and. (p(3) == this%L(3)) ) p(3) = 0
pure integer function, public compact_p_to_h(p, m)
integer, parameter, public periodic_bc
subroutine random_shift(this, state)
subroutine sort_particles(this, position_old, position_new)
integer, parameter, public specular_bc
subroutine init(this, L, a, has_walls)
Compute compact Hilbert indices.
subroutine count_particles(this, position)
integer function, dimension(3) cartesian_indices(this, position)
integer, parameter, public bounce_back_bc