21#include "./base/base_uses.f90"
28 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'gw_ri_rs_grid_setup_main'
40 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT) :: grid_points(:, :)
42 IF (bs_env%ri_rs%grid_opt%enabled)
THEN
59 CALL assemble_ri_rs_grid(bs_env, grid_points)
68 SUBROUTINE assemble_ri_rs_grid(bs_env, ri_rs_grid_points)
70 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT) :: ri_rs_grid_points(:, :)
72 CHARACTER(LEN=*),
PARAMETER :: routinen =
'assemble_ri_rs_grid'
76 CALL timeset(routinen, handle)
78 cpassert(
ALLOCATED(bs_env%ri_rs%atomic_grids))
79 CALL assemble_ri_rs_grid_points(bs_env, ri_rs_grid_points)
80 CALL release_atomic_grids(bs_env)
84 END SUBROUTINE assemble_ri_rs_grid
91 SUBROUTINE assemble_ri_rs_grid_points(bs_env, ri_rs_grid_points)
93 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT) :: ri_rs_grid_points(:, :)
95 INTEGER :: atom_grid_end, atom_grid_start, iatom, &
97 INTEGER,
ALLOCATABLE :: atom_grid_offsets(:), atom_order(:)
98 REAL(kind=
dp) :: atom_center(3)
100 natom = bs_env%n_atom
101 CALL spatial_atom_order(bs_env%ri_rs%particle_set, atom_order)
103 ALLOCATE (bs_env%ri_rs%grid_atom_boundaries(natom + 1), atom_grid_offsets(natom))
104 bs_env%ri_rs%n_grid_points = 0
105 DO ilayout = 1, natom
106 iatom = atom_order(ilayout)
107 atom_grid_offsets(iatom) = bs_env%ri_rs%n_grid_points + 1
108 bs_env%ri_rs%grid_atom_boundaries(ilayout) = bs_env%ri_rs%n_grid_points + 1
109 bs_env%ri_rs%n_grid_points = bs_env%ri_rs%n_grid_points + &
110 bs_env%ri_rs%atomic_grids(iatom)%npts
112 bs_env%ri_rs%grid_atom_boundaries(natom + 1) = bs_env%ri_rs%n_grid_points + 1
114 IF (bs_env%unit_nr > 0)
THEN
115 WRITE (bs_env%unit_nr, fmt=
"(T2,A,T69,I12)") &
116 'Total grid points used for RI-RS:', bs_env%ri_rs%n_grid_points
117 WRITE (bs_env%unit_nr,
"(A)")
' '
120 ALLOCATE (ri_rs_grid_points(3, bs_env%ri_rs%n_grid_points))
126 atom_center(:) = bs_env%ri_rs%particle_set(iatom)%r(:)
127 atom_grid_start = atom_grid_offsets(iatom)
128 atom_grid_end = atom_grid_start + bs_env%ri_rs%atomic_grids(iatom)%npts - 1
130 ri_rs_grid_points(1, atom_grid_start:atom_grid_end) = &
131 bs_env%ri_rs%atomic_grids(iatom)%raw_points(1, :) + atom_center(1)
132 ri_rs_grid_points(2, atom_grid_start:atom_grid_end) = &
133 bs_env%ri_rs%atomic_grids(iatom)%raw_points(2, :) + atom_center(2)
134 ri_rs_grid_points(3, atom_grid_start:atom_grid_end) = &
135 bs_env%ri_rs%atomic_grids(iatom)%raw_points(3, :) + atom_center(3)
138 END SUBROUTINE assemble_ri_rs_grid_points
144 SUBROUTINE release_atomic_grids(bs_env)
149 DO iatom = 1,
SIZE(bs_env%ri_rs%atomic_grids)
150 DEALLOCATE (bs_env%ri_rs%atomic_grids(iatom)%raw_points)
152 DEALLOCATE (bs_env%ri_rs%atomic_grids)
153 END SUBROUTINE release_atomic_grids
160 SUBROUTINE spatial_atom_order(particle_set, order)
162 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: order
164 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spatial_atom_order'
165 INTEGER,
PARAMETER :: nbits = 21
167 INTEGER :: handle, iatom, idimension, natom
168 INTEGER(KIND=int_8) :: cmax, integer_coordinate(3), m1, m2, m3
169 INTEGER(KIND=int_8),
ALLOCATABLE :: morton_code(:)
170 REAL(kind=
dp) :: hi(3), lo(3), span(3)
172 CALL timeset(routinen, handle)
174 natom =
SIZE(particle_set)
175 ALLOCATE (order(natom), morton_code(natom))
176 cmax = ishft(1_int_8, nbits) - 1_int_8
179 hi(:) = -huge(1.0_dp)
182 lo(idimension) = min(lo(idimension), particle_set(iatom)%r(idimension))
183 hi(idimension) = max(hi(idimension), particle_set(iatom)%r(idimension))
186 span(:) = hi(:) - lo(:)
188 IF (span(idimension) <= 0.0_dp) span(idimension) = 1.0_dp
193 integer_coordinate(idimension) = &
194 int(((particle_set(iatom)%r(idimension) - lo(idimension))/span(idimension))* &
196 integer_coordinate(idimension) = &
197 min(cmax, max(0_int_8, integer_coordinate(idimension)))
199 CALL morton_split3(integer_coordinate(1), m1)
200 CALL morton_split3(integer_coordinate(2), m2)
201 CALL morton_split3(integer_coordinate(3), m3)
202 morton_code(iatom) = ior(ior(m1, ishft(m2, 1)), ishft(m3, 2))
205 CALL sort(morton_code, natom, order)
206 DEALLOCATE (morton_code)
208 CALL timestop(handle)
210 END SUBROUTINE spatial_atom_order
217 SUBROUTINE morton_split3(input_integer, spread_integer)
218 INTEGER(KIND=int_8),
INTENT(IN) :: input_integer
219 INTEGER(KIND=int_8),
INTENT(OUT) :: spread_integer
221 spread_integer = iand(input_integer, int(z
'1FFFFF',
int_8))
222 spread_integer = iand(ior(spread_integer, ishft(spread_integer, 32)), &
223 int(z
'1F00000000FFFF',
int_8))
224 spread_integer = iand(ior(spread_integer, ishft(spread_integer, 16)), &
225 int(z
'1F0000FF0000FF',
int_8))
226 spread_integer = iand(ior(spread_integer, ishft(spread_integer, 8)), &
227 int(z
'100F00F00F00F00F',
int_8))
228 spread_integer = iand(ior(spread_integer, ishft(spread_integer, 4)), &
229 int(z
'10C30C30C30C30C3',
int_8))
230 spread_integer = iand(ior(spread_integer, ishft(spread_integer, 2)), &
231 int(z
'1249249249249249',
int_8))
232 END SUBROUTINE morton_split3
Read pretabulated atom-relative RI-RS grids from data files.
subroutine, public read_ri_rs_grid_from_file(bs_env)
Read pretabulated atom-relative RI-RS grids from the CP2K data files.
Optimize automatically initialized atom-centred RI-RS grids.
subroutine, public optimize_ri_rs_grid(bs_env)
Initialize Lebedev grids and subsequently optimize their grid-point coordinates.
Main setup file for RI-RS grids {r_l}.
subroutine, public setup_ri_rs_grid(bs_env, grid_points)
Get RI-RS grid points {r_l}, either by on-the-fly optimization or reading pretabulated atomic grids.
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
Define the data structure for the particle information.
All kind of helpful little routines.