43 integer,
allocatable :: count(:,:,:)
44 double precision,
allocatable :: v(:,:,:,:)
45 double precision :: r_min
46 double precision :: r_max
47 double precision :: dr
48 double precision :: dtheta
49 type(
timer_t),
pointer :: time_polar_update
58 subroutine init(this, N_species, N_r, r_min, r_max, N_theta)
60 integer,
intent(in) :: N_species
61 integer,
intent(in) :: N_r
62 double precision,
intent(in) :: r_min
63 double precision,
intent(in) :: r_max
64 integer,
intent(in) :: N_theta
66 allocate(this%count(n_species, n_theta, n_r))
67 allocate(this%v(2, n_species, n_theta, n_r))
74 this%dr = (r_max - r_min) / n_r
75 this%dtheta =
pi/n_theta
77 allocate(this%time_polar_update)
78 call this%time_polar_update%init(
'polar_update')
83 subroutine update(this, x, v, unit_r, solvent, cells)
85 double precision,
intent(in) :: x(3)
86 double precision,
intent(in) :: v(3)
87 double precision,
intent(in) :: unit_r(3)
91 double precision :: r_min, r_min_sq, r_max, r_max_sq, dr, dtheta
92 double precision :: r_sq, v_r, v_th, r, theta
93 double precision,
dimension(3) :: d, one_r, out_of_plane, one_theta, L
94 double precision,
dimension(3) :: solvent_v
95 integer :: idx, s2, i_r, i_th
97 integer,
allocatable :: this_count(:,:,:)
98 double precision,
allocatable :: this_v(:,:,:,:)
100 integer :: cell_idx, start, n
101 integer :: n_species, n_theta, n_r
111 n_species =
size(this%count, dim=1)
112 n_theta =
size(this%count, dim=2)
113 n_r =
size(this%count, dim=3)
115 allocate(this_v(2, n_species, n_theta, n_r))
116 allocate(this_count(n_species, n_theta, n_r))
120 call this%time_polar_update%tic()
125 do cell_idx = 1, cells%N
129 start = cells% cell_start(cell_idx)
130 n = cells% cell_count(cell_idx)
132 do idx = start, start + n - 1
133 s2 = solvent%species(idx)
135 d =
rel_pos(solvent%pos(:,idx), x, l)
137 if (( r_sq >= r_min_sq ) .and. ( r_sq < r_max_sq ))
then 140 i_r = floor((r-r_min)/dr) + 1
141 theta = acos( dot_product(unit_r,d)/r )
142 i_th = floor(theta/dtheta) + 1
145 out_of_plane =
cross(unit_r, one_r)
146 one_theta =
cross(out_of_plane, one_r)
147 one_theta = one_theta/norm2(one_theta)
148 solvent_v = solvent%vel(:,idx) - v
149 v_r = dot_product(solvent_v, one_r)
150 v_th = dot_product(solvent_v, one_theta)
151 this_v(:, s2, i_th, i_r) = this_v(:, s2, i_th, i_r) + [v_r, v_th]
152 this_count(s2, i_th, i_r) = this_count(s2, i_th, i_r) + 1
157 this%v = this%v + this_v
158 this%count = this%count + this_count
161 deallocate(this_count)
163 call this%time_polar_update%tac()
Derived type and routines for neighbor listing.
pure double precision function, dimension(3), public cross(x1, x2)
subroutine init(this, L, a, has_walls)
subroutine update(this, x, v, unit_r, solvent, cells)
Update the fields.
pure double precision function, dimension(3), public rel_pos(x, y, L)
Return x-y distance with minimum image convention.
Routines to compute polar concentration and velocity profiles.
double precision, parameter, public pi