29 integer :: block_length
33 double precision,
allocatable ::
value(:,:,:,:)
34 double precision,
allocatable :: correlation(:,:,:,:)
35 integer,
allocatable :: count(:)
37 procedure,
public :: init
38 procedure,
public :: add
57 subroutine init(this, l, b, dim, n)
59 integer,
intent(in) :: l, b
60 integer,
intent(in),
optional :: dim
61 integer,
intent(in),
optional :: n
63 if (
present(dim))
then 78 allocate(this%value(this%dim, this%n, l, b))
79 allocate(this%correlation(this%dim, this%n, l, b))
80 allocate(this%count(b))
82 this%value(:,:,:,:) = 0
83 this%correlation(:,:,:,:) = 0
89 subroutine add(this, i, block_operation, x, x_n, xvec, xvec_n)
91 integer,
intent(in) :: i
92 double precision,
intent(in),
optional :: x
93 double precision,
intent(in),
optional :: x_n(:)
94 double precision,
intent(in),
optional :: xvec(:)
95 double precision,
intent(in),
optional :: xvec_n(:,:)
97 subroutine block_operation(s, c, idx, l, n, dim)
98 double precision,
intent(in) :: s(:,:,:)
99 double precision,
intent(inout) :: c(:,:,:)
100 integer,
intent(in) :: idx
101 integer,
intent(in) :: l, n, dim
102 end subroutine block_operation
106 integer :: i_block, normed_idx, x_count
107 double precision,
allocatable :: x_gen(:,:)
110 allocate(x_gen(this%dim, this%n))
114 else if (
present(x_n))
then 117 else if (
present(xvec))
then 120 else if (
present(xvec_n))
then 125 if (x_count/=1) stop
'multiple (or no) arguments to correlator_t add' 127 l = this%block_length
130 block_loop:
do i_block = 0, b-1
131 if (modulo(i, l**i_block) /= 0)
exit block_loop
132 normed_idx = modulo(i / l**i_block, l)
133 this%value(:, :, normed_idx+1, i_block+1) = x_gen
134 if (i > l**(i_block+1))
then 136 call block_operation(this%value(:,:,:,i_block+1), &
137 this%correlation(:,:,:,i_block+1), normed_idx, l, this%n, this%dim)
138 this%count(i_block+1) = this%count(i_block+1) + 1
148 double precision,
intent(in) :: s(:,:,:)
149 double precision,
intent(inout) :: c(:,:,:)
150 integer,
intent(in) :: idx, l, n, dim
152 integer :: i, j, n_idx
153 double precision :: current(dim,n)
155 current = s(:,:,idx+1)
158 j = modulo(idx-i, l) + 1
160 c(:, n_idx, j) = c(:, n_idx, j) + (current(:,n_idx)*s(:,n_idx,i+1))
168 double precision,
intent(in) :: s(:,:,:)
169 double precision,
intent(inout) :: c(:,:,:)
170 integer,
intent(in) :: idx, l, n, dim
172 integer :: i, j, n_idx
173 double precision :: current(dim, n)
175 current = s(:,:,idx+1)
178 j = modulo(idx-i, l) + 1
180 c(:, n_idx, j) = c(:, n_idx, j) + (current(:,n_idx)-s(:,n_idx,i+1))**2
187 function get_n_blocks(l, n_blocks_max, n_samples)
result(n_blocks)
188 integer,
intent(in) :: l, n_blocks_max, n_samples
192 if (l**n_blocks >= n_samples/l)
exit 198 subroutine axial_init(this, block_length, n_samples, n_samples_fast)
200 integer,
intent(in) :: block_length, n_samples, n_samples_fast
205 call this%msd%init(block_length, n_blocks, dim=3)
206 call this%oacf%init(block_length, n_blocks, dim=3)
208 n_blocks =
get_n_blocks(block_length, 8, n_samples_fast)
209 call this%vacf%init(block_length, n_blocks, dim=3)
210 call this%parallel_vacf%init(block_length, n_blocks, dim=3)
211 call this%transverse_vacf%init(block_length, n_blocks, dim=3)
216 subroutine axial_add(this, i, com_pos, unit_r)
218 integer,
intent(in) :: i
219 double precision,
intent(in) :: com_pos(3), unit_r(3)
229 integer,
intent(in) :: i
230 double precision,
intent(in) :: v_com(3), unit_r(3)
232 double precision :: parallel_v(3), transverse_v(3)
234 parallel_v = dot_product(v_com, unit_r) * unit_r
235 transverse_v = v_com - parallel_v
243 subroutine axial_write(this, correlator_group, sampling, dt, fast_sampling, fast_dt)
247 integer(HID_T) :: correlator_group
248 integer,
intent(in) :: sampling, fast_sampling
249 double precision,
intent(in) :: dt, fast_dt
252 this%msd, sampling, dt)
254 this%oacf, sampling, dt)
257 this%vacf, fast_sampling, fast_dt)
259 this%parallel_vacf, fast_sampling, fast_dt)
261 this%transverse_vacf, fast_sampling, fast_dt)
270 integer(HID_T),
intent(inout) :: loc
271 character(len=*),
intent(in) :: name
273 integer,
intent(in) :: step
274 double precision,
intent(in) :: time
276 integer(HID_T) :: group
279 call h5gcreate_f(loc, name, group, error)
280 call h5md_write_dataset(group,
'value', c%correlation)
281 call h5md_write_dataset(group,
'count', c%count)
282 call h5md_write_dataset(group,
'step', step)
283 call h5md_write_dataset(group,
'time', time)
284 call h5gclose_f(group, error)
subroutine, public write_correlator_block(loc, name, c, step, time)
Write the data from a correlator_t variable to a HDF5 group.
subroutine axial_init(this, block_length, n_samples, n_samples_fast)
Initialize an axial correlator.
subroutine add(this, i, block_operation, x, x_n, xvec, xvec_n)
Add a data element to the correlator.
subroutine axial_add_fast(this, i, v_com, unit_r)
Add a data element to an axial correlator (fast time scale)
subroutine init(this, l, b, dim, n)
Initialize a correlator_t variable.
subroutine axial_add(this, i, com_pos, unit_r)
Add a data element to an axial correlator (slow time scale)
integer function, public get_n_blocks(l, n_blocks_max, n_samples)
Return the number of blocks needed for a trajectory of length n_samples.
subroutine, public correlate_block_dot(s, c, idx, l, n, dim)
Correlation routine for dot product.
subroutine axial_write(this, correlator_group, sampling, dt, fast_sampling, fast_dt)
Write all correlators from an axial correlator variable to a HDF5 group.
subroutine, public correlate_block_distsq(s, c, idx, l, n, dim)
Correlation routine for squared distance.