Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief routines that build the integrals of the Vxc potential calculated
10 : !> for the atomic density in the basis set of spherical primitives
11 : ! **************************************************************************************************
12 : MODULE qs_vxc_atom
13 : USE atomic_kind_types, ONLY: atomic_kind_type,&
14 : get_atomic_kind
15 : USE basis_set_types, ONLY: gto_basis_set_type
16 : USE cell_types, ONLY: cell_type
17 : USE cp_array_utils, ONLY: cp_3d_r_cp_type
18 : USE cp_control_types, ONLY: dft_control_type
19 : USE cp_log_handling, ONLY: cp_logger_get_default_io_unit
20 : USE external_potential_types, ONLY: gth_potential_type,&
21 : sgp_potential_type
22 : USE input_constants, ONLY: cdft_alpha_constraint,&
23 : cdft_beta_constraint,&
24 : cdft_charge_constraint,&
25 : cdft_magnetization_constraint,&
26 : xc_none
27 : USE input_section_types, ONLY: section_get_rval,&
28 : section_vals_get_subs_vals,&
29 : section_vals_type,&
30 : section_vals_val_get
31 : USE kinds, ONLY: dp,&
32 : int_8
33 : USE lebedev, ONLY: deallocate_lebedev_grids,&
34 : get_number_of_lebedev_grid,&
35 : init_lebedev_grids,&
36 : lebedev_grid
37 : USE memory_utilities, ONLY: reallocate
38 : USE message_passing, ONLY: mp_para_env_type
39 : USE orbital_pointers, ONLY: indco,&
40 : indso,&
41 : nco,&
42 : ncoset,&
43 : nsoset
44 : USE orbital_transformation_matrices, ONLY: orbtramat
45 : USE particle_types, ONLY: particle_type
46 : USE pw_env_types, ONLY: pw_env_get,&
47 : pw_env_type
48 : USE pw_grid_types, ONLY: pw_grid_type
49 : USE pw_methods, ONLY: pw_axpy
50 : USE pw_pool_types, ONLY: pw_pool_type
51 : USE pw_types, ONLY: pw_c1d_gs_type,&
52 : pw_r3d_rs_type
53 : USE qs_cdft_grid, ONLY: cdft_point_context_create,&
54 : cdft_point_context_release,&
55 : cdft_point_context_type,&
56 : cdft_point_weights
57 : USE qs_cdft_types, ONLY: cdft_control_type
58 : USE qs_environment_types, ONLY: get_qs_env,&
59 : qs_environment_type
60 : USE qs_force_types, ONLY: qs_force_type
61 : USE qs_grid_atom, ONLY: allocate_grid_atom,&
62 : create_grid_atom,&
63 : grid_atom_type
64 : USE qs_harmonics_atom, ONLY: harmonics_atom_type
65 : USE qs_kind_types, ONLY: get_qs_kind,&
66 : has_nlcc,&
67 : qs_kind_type
68 : USE qs_linres_types, ONLY: nablavks_atom_type
69 : USE qs_native_grid_cache, ONLY: fetch_native_grid_stencil,&
70 : native_grid_interp_npts,&
71 : native_grid_interp_offset_max,&
72 : native_grid_interp_offset_min,&
73 : native_grid_interpolation_stencil_type,&
74 : prepare_native_grid_cache,&
75 : store_native_grid_stencil
76 : USE qs_rho_atom_methods, ONLY: replicate_rho_atom_radial
77 : USE qs_rho_atom_types, ONLY: get_rho_atom,&
78 : rho_atom_coeff,&
79 : rho_atom_type
80 : USE qs_rho_types, ONLY: qs_rho_get,&
81 : qs_rho_type
82 : USE qs_vxc_atom_utils, ONLY: &
83 : calc_rho_angular, calc_rho_nlcc, calc_tau_atom, create_tau_basis_cache, dgaVtaudgb, &
84 : evaluate_nlcc_primitive_fields, gaVxcgb_GC, gaVxcgb_noGC, gapw_atom_grid_support_radius, &
85 : release_tau_basis_cache, tau_basis_cache_type
86 : USE skala_gpw_features, ONLY: build_periodic_atom_image_layout,&
87 : periodic_atom_image_partition,&
88 : periodic_atom_image_partition_from_layout,&
89 : skala_gpw_smooth_partition_derivatives,&
90 : smooth_atom_partition,&
91 : smooth_partition_atomic_weight_scale,&
92 : smooth_partition_atomic_weight_scale_derivative
93 : USE skala_gpw_functional, ONLY: &
94 : build_vxc_from_feature_grads, get_gauxc_section, native_skala_gapw_density_partition, &
95 : skala_gapw_atom_composite_energy, skala_gapw_atom_vxc_of_r, &
96 : skala_gapw_density_partition_hard_minus_soft, skala_gapw_density_partition_hard_only, &
97 : skala_gapw_density_partition_none, skala_gapw_density_partition_soft_only, &
98 : xc_section_uses_gauxc_model, xc_section_uses_native_skala_evaluator
99 : USE spherical_harmonics, ONLY: y_lm
100 : USE util, ONLY: get_limit
101 : USE virial_types, ONLY: virial_type
102 : USE xc_atom, ONLY: fill_rho_set,&
103 : vxc_of_r_epr,&
104 : vxc_of_r_new,&
105 : xc_rho_set_atom_update
106 : USE xc_derivative_set_types, ONLY: xc_derivative_set_type,&
107 : xc_dset_create,&
108 : xc_dset_release,&
109 : xc_dset_zero_all
110 : USE xc_derivatives, ONLY: xc_functionals_get_needs
111 : USE xc_input_constants, ONLY: skala_gapw_cp2k_default,&
112 : skala_gapw_direct_valence,&
113 : skala_gapw_paw_one_center,&
114 : skala_gapw_paw_one_center_split
115 : USE xc_rho_cflags_types, ONLY: xc_rho_cflags_type
116 : USE xc_rho_set_types, ONLY: xc_rho_set_create,&
117 : xc_rho_set_get,&
118 : xc_rho_set_release,&
119 : xc_rho_set_type,&
120 : xc_rho_set_update
121 : #include "./base/base_uses.f90"
122 :
123 : IMPLICIT NONE
124 :
125 : PRIVATE
126 :
127 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vxc_atom'
128 :
129 : ! A wrapped stencil can touch both end tiles and one adjacent interior tile when the final
130 : ! tile is shorter than the stencil. Three tiles per direction are therefore sufficient.
131 : INTEGER, PARAMETER, PRIVATE :: native_grid_adjoint_tile_edge = 64, &
132 : native_grid_adjoint_max_tiles_per_direction = 3, &
133 : native_grid_adjoint_max_bins_per_row = &
134 : native_grid_adjoint_max_tiles_per_direction**3
135 :
136 : PUBLIC :: calculate_vxc_atom, &
137 : calculate_vxc_atom_epr, &
138 : gapw_cdft_one_center
139 :
140 : ! **************************************************************************************************
141 :
142 : CONTAINS
143 :
144 : ! **************************************************************************************************
145 : !> \brief Initialize atom-centered quadrature for native Skala layouts.
146 : !> \param kind_set quantum kinds
147 : !> \param dft_control DFT controls supplying the radial quadrature
148 : ! **************************************************************************************************
149 264 : SUBROUTINE ensure_native_skala_atom_grids(kind_set, dft_control)
150 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: kind_set
151 : TYPE(dft_control_type), POINTER :: dft_control
152 :
153 : INTEGER :: ikind, ll, na, nr, quadrature
154 : TYPE(grid_atom_type), POINTER :: grid_atom
155 :
156 264 : quadrature = dft_control%qs_control%gapw_control%quadrature
157 264 : CALL init_lebedev_grids()
158 574 : DO ikind = 1, SIZE(kind_set)
159 310 : NULLIFY (grid_atom)
160 310 : CALL get_qs_kind(kind_set(ikind), grid_atom=grid_atom, ngrid_ang=na, ngrid_rad=nr)
161 310 : IF (ASSOCIATED(grid_atom)) THEN
162 284 : IF (ASSOCIATED(grid_atom%weight) .AND. grid_atom%nr == nr) CYCLE
163 : ELSE
164 26 : CALL allocate_grid_atom(kind_set(ikind)%grid_atom)
165 26 : grid_atom => kind_set(ikind)%grid_atom
166 : END IF
167 26 : ll = get_number_of_lebedev_grid(n=na)
168 26 : na = lebedev_grid(ll)%n
169 26 : grid_atom%ng_sphere = na
170 26 : grid_atom%nr = nr
171 600 : CALL create_grid_atom(grid_atom, nr, na, 0, ll, quadrature)
172 : END DO
173 264 : CALL deallocate_lebedev_grids()
174 :
175 264 : END SUBROUTINE ensure_native_skala_atom_grids
176 :
177 : ! **************************************************************************************************
178 : !> \brief Decide whether a kind contributes hard-minus-soft primitive fields.
179 : !> \param paw_atom whether CP2K constructed a one-center representation for the kind
180 : !> \param gapw_representation requested Skala pseudopotential GAPW representation
181 : !> \param has_pseudopotential whether the kind uses a GTH or semi-global pseudopotential
182 : !> \param zeff valence charge of the potential
183 : !> \param zatom atomic number
184 : !> \return true when hard-minus-soft fields contribute for this kind
185 : ! **************************************************************************************************
186 564 : PURE FUNCTION native_skala_uses_one_center_kind( &
187 : paw_atom, gapw_representation, has_pseudopotential, zeff, zatom) RESULT(use_one_center)
188 : LOGICAL, INTENT(IN) :: paw_atom
189 : INTEGER, INTENT(IN) :: gapw_representation
190 : LOGICAL, INTENT(IN) :: has_pseudopotential
191 : REAL(dp), INTENT(IN) :: zeff
192 : INTEGER, INTENT(IN) :: zatom
193 : LOGICAL :: use_one_center
194 :
195 564 : use_one_center = paw_atom
196 564 : IF (.NOT. use_one_center) RETURN
197 :
198 620 : SELECT CASE (gapw_representation)
199 : CASE (skala_gapw_direct_valence)
200 70 : use_one_center = .NOT. has_pseudopotential
201 : CASE (skala_gapw_paw_one_center, skala_gapw_paw_one_center_split)
202 16 : CONTINUE
203 : CASE (skala_gapw_cp2k_default)
204 16 : IF (has_pseudopotential .AND. &
205 566 : ABS(zeff - REAL(zatom, dp)) <= 1.0E-10_dp) use_one_center = .FALSE.
206 : END SELECT
207 :
208 : END FUNCTION native_skala_uses_one_center_kind
209 :
210 : ! **************************************************************************************************
211 : !> \brief ...
212 : !> \param qs_env ...
213 : !> \param energy_only ...
214 : !> \param exc1 the on-body ex energy contribution
215 : !> \param adiabatic_rescale_factor ...
216 : !> \param kind_set_external provides a non-default kind_set to use
217 : !> \param rho_atom_set_external provides a non-default atomic density set to use
218 : !> \param xc_section_external provides an external non-default XC
219 : !> \param calculate_forces ...
220 : !> \param composite_vxc_rho ...
221 : !> \param composite_vxc_tau ...
222 : !> \param composite_reference_active ...
223 : !> \param direct_valence_atom_grid evaluate the smooth valence fields on atom-centered grids
224 : !> \param atom_composite_grid evaluate GAPW primitive fields on atom-centered composite grids
225 : ! **************************************************************************************************
226 32836 : SUBROUTINE calculate_vxc_atom(qs_env, energy_only, exc1, &
227 : adiabatic_rescale_factor, kind_set_external, &
228 : rho_atom_set_external, xc_section_external, calculate_forces, &
229 : composite_vxc_rho, composite_vxc_tau, composite_reference_active, &
230 : direct_valence_atom_grid, atom_composite_grid)
231 :
232 : TYPE(qs_environment_type), POINTER :: qs_env
233 : LOGICAL, INTENT(IN) :: energy_only
234 : REAL(dp), INTENT(INOUT) :: exc1
235 : REAL(dp), INTENT(IN), OPTIONAL :: adiabatic_rescale_factor
236 : TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
237 : POINTER :: kind_set_external
238 : TYPE(rho_atom_type), DIMENSION(:), OPTIONAL, &
239 : POINTER :: rho_atom_set_external
240 : TYPE(section_vals_type), OPTIONAL, POINTER :: xc_section_external
241 : LOGICAL, INTENT(IN), OPTIONAL :: calculate_forces
242 : TYPE(pw_r3d_rs_type), DIMENSION(:), OPTIONAL, &
243 : POINTER :: composite_vxc_rho, composite_vxc_tau
244 : LOGICAL, INTENT(OUT), OPTIONAL :: composite_reference_active
245 : LOGICAL, INTENT(IN), OPTIONAL :: direct_valence_atom_grid, &
246 : atom_composite_grid
247 :
248 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom'
249 :
250 : INTEGER :: adjoint_bin, adjoint_entry, adjoint_nbins, adjoint_nchannels, &
251 : adjoint_tile_count(3), adjoint_tile_lower(3), adjoint_tile_upper(3), &
252 : atom_composite_components, bo(2), composite_descriptor_target_image, &
253 : composite_image_periodicity(3), composite_local_atom, composite_local_natom, &
254 : composite_nflat, composite_partition_target_image, composite_pw_nflat, composite_row, &
255 : gapw_density_partition, gapw_representation, handle, ia, iat, iatom, icomponent, idir, &
256 : ikind, image_i1, image_i2, image_i3, image_lower(3), image_shell(3), image_shift(3), &
257 : image_upper(3), ir, ispin, iw, jdir, myfun, na
258 : INTEGER :: natom, nr, nspins, num_pe, source_atom, target_atom, xc_deriv_method_id, &
259 : xc_rho_smooth_id, zatom
260 32836 : INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:) :: composite_atomic_grid_sizes, &
261 32836 : composite_local_grid_sizes
262 32836 : INTEGER, ALLOCATABLE, DIMENSION(:) :: adjoint_bin_offsets, adjoint_bin_rows, &
263 32836 : composite_atom_end, composite_atom_kind, composite_atom_kind_index, composite_atom_start, &
264 32836 : composite_grid_atom, composite_local_atoms
265 : INTEGER, DIMENSION(2, 3) :: bounds
266 32836 : INTEGER, DIMENSION(:), POINTER :: atom_list
267 : LOGICAL :: accint, atom_composite_active, atom_composite_diagnostic, &
268 : atom_composite_reference, direct_valence_atom_composite, donlcc, evaluate_hard, &
269 : evaluate_soft, gradient_f, image_partition_atom_composite, lsd, my_calculate_forces, &
270 : native_grid_diagnostics, nlcc, one_center_kind, paw_atom, paw_pseudopotentials, &
271 : requested_atom_composite_grid, rho_g_valid, skala_atom_grid, source_matrix_local, tau_f, &
272 : tau_r_valid, use_atom_composite_density, use_atom_composite_gradient, &
273 : use_atom_composite_tau, use_virial
274 32836 : LOGICAL, ALLOCATABLE, DIMENSION(:) :: composite_partition_included
275 : REAL(dp) :: agr, alpha, atom_composite_exc, atom_composite_nelec, &
276 : composite_cross_cutoff_max, composite_cross_density_max, composite_cross_grad_max, &
277 : composite_cross_kin_max, composite_density_max, composite_density_min, &
278 : composite_grad_max, composite_kin_max, composite_kin_min, composite_tau_integral, &
279 : cross_cutoff, density_cut, descriptor_window_adjoint, descriptor_window_weight, exc_h, &
280 : exc_s, feature_vxc_analytic, feature_vxc_fd, feature_vxc_minus, feature_vxc_plus, &
281 : feature_vxc_step, gradient_cut, local_partition_weight, my_adiabatic_rescale_factor, &
282 : nlcc_density, nlcc_spin_factor
283 : REAL(dp) :: one_center_density_field_contraction, one_center_density_matrix_contraction, &
284 : one_center_field_contraction, one_center_gradient_field_contraction, &
285 : one_center_gradient_matrix_contraction, one_center_matrix_contraction, &
286 : one_center_rho_grad_field_contraction, one_center_rho_grad_matrix_contraction, &
287 : one_center_tau_field_contraction, one_center_tau_matrix_contraction, &
288 : one_center_tensor_contraction, partition_adjoint, partition_scale, partition_weight, &
289 : smooth_grid_contraction, smooth_input_contraction, target_partition_adjoint, tau_cut, zeff
290 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: composite_atomic_grid_weight_grad, &
291 32836 : composite_atomic_grid_weights, composite_base_grid_weights, composite_distances, &
292 32836 : composite_grid_weight_grad, composite_grid_weights, composite_partition_weights
293 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: composite_atom_coord_grad, composite_atom_coords, &
294 32836 : composite_cross_density, composite_cross_force, composite_cross_force_local, &
295 32836 : composite_cross_kin, composite_density, composite_density_grad, &
296 32836 : composite_descriptor_image_coords, composite_explicit_force, composite_grid_coord_force, &
297 32836 : composite_grid_coord_grad, composite_grid_coords, composite_kin, composite_kin_grad, &
298 32836 : composite_local_atom_coords, composite_model_atom_force, composite_moving_smooth_force, &
299 32836 : composite_nlcc_center_force, composite_nlcc_center_force_local, &
300 32836 : composite_nlcc_target_force
301 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: composite_partition_atom_coords, &
302 32836 : composite_partition_force, composite_partition_force_local, &
303 32836 : composite_partition_image_coords, composite_smooth_density_cache, &
304 65672 : composite_smooth_kin_cache, local_partition_datom
305 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:, :), TARGET :: smooth_density_adjoint_storage, &
306 32836 : smooth_kin_adjoint_storage
307 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:, :, :) :: composite_cross_grad, composite_grad, &
308 32836 : composite_grad_grad, composite_int_h, composite_int_s, composite_partition_datom, &
309 98508 : composite_partition_dstrain, composite_smooth_gradient_cache, vtau_h_local, vtau_s_local, &
310 32836 : vxc_h_local, vxc_s_local
311 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:, :, :), TARGET :: smooth_grad_adjoint_storage
312 32836 : REAL(dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: vxg_h_local, vxg_s_local
313 : REAL(dp), DIMENSION(1, 1, 1) :: tau_d
314 : REAL(dp), DIMENSION(1, 1, 1, 1) :: rho_d
315 : REAL(dp), DIMENSION(2) :: composite_smooth_density_adjoint_value, &
316 : composite_smooth_density_value, composite_smooth_kin_adjoint_value, &
317 : composite_smooth_kin_value, cross_density, cross_density_adjoint, cross_kin, &
318 : cross_kin_adjoint
319 : REAL(dp), DIMENSION(3) :: composite_point, cross_displacement, cross_spatial_derivative, &
320 : fractional, image_translation, nlcc_gradient, nlcc_spatial_derivative, &
321 : skala_atom_force_h, skala_atom_force_s, spatial_derivative
322 : REAL(dp), DIMENSION(3, 1) :: local_descriptor_datom
323 : REAL(dp), DIMENSION(3, 2) :: composite_smooth_gradient_adjoint_value, &
324 : composite_smooth_gradient_value, cross_density_spatial, cross_grad, cross_grad_adjoint, &
325 : cross_kin_spatial
326 : REAL(dp), DIMENSION(3, 3) :: composite_cross_image_virial, &
327 : composite_cross_image_virial_local, composite_explicit_virial, composite_feature_virial, &
328 : composite_interpolation_virial, composite_partition_strain_virial, &
329 : local_descriptor_dstrain, local_partition_dstrain, nlcc_hessian, skala_atom_virial, &
330 : skala_atom_virial_h, skala_atom_virial_s
331 : REAL(dp), DIMENSION(3, 3, 2) :: cross_grad_spatial
332 : REAL(dp), DIMENSION(4) :: feature_component_analytic, &
333 : feature_component_fd
334 65672 : REAL(dp), DIMENSION(:, :), POINTER :: rho_nlcc, smooth_density_adjoint, &
335 65672 : smooth_kin_adjoint, weight_h, weight_s
336 32836 : REAL(dp), DIMENSION(:, :, :), POINTER :: composite_smooth_rho, composite_smooth_rhoa, &
337 32836 : composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
338 131344 : composite_smooth_tau_b, rho_h, rho_s, smooth_grad_adjoint, smooth_rho, smooth_rhoa, &
339 32836 : smooth_rhob, smooth_tau, smooth_tau_a, smooth_tau_b, tau_h, tau_s, vtau_h, vtau_s, vxc_h, &
340 32836 : vxc_s
341 65672 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s, vxg_h, vxg_s
342 32836 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
343 : TYPE(cell_type), POINTER :: cell
344 229852 : TYPE(cp_3d_r_cp_type), DIMENSION(3) :: composite_smooth_drho, composite_smooth_drhoa, &
345 459704 : composite_smooth_drhob, smooth_drho, smooth_drhoa, smooth_drhob
346 : TYPE(dft_control_type), POINTER :: dft_control
347 : TYPE(grid_atom_type), POINTER :: grid_atom
348 : TYPE(gth_potential_type), POINTER :: gth_potential
349 : TYPE(gto_basis_set_type), POINTER :: basis_1c
350 : TYPE(harmonics_atom_type), POINTER :: harmonics
351 : TYPE(mp_para_env_type), POINTER :: para_env
352 : TYPE(native_grid_interpolation_stencil_type) :: interpolation_stencil
353 32836 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
354 32836 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: smooth_rho_g
355 : TYPE(pw_env_type), POINTER :: pw_env
356 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
357 65672 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: smooth_rho_r, smooth_tau_r, &
358 32836 : smooth_vxc_rho, smooth_vxc_tau
359 32836 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
360 32836 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: my_kind_set
361 : TYPE(qs_rho_type), POINTER :: rho_struct
362 32836 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: cpc_h, cpc_s, dr_h, dr_s, int_hh, &
363 65672 : int_ss, r_h, r_s
364 32836 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
365 32836 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: my_rho_atom_set
366 : TYPE(rho_atom_type), POINTER :: rho_atom
367 : TYPE(section_vals_type), POINTER :: gauxc_section, input, my_xc_section, &
368 : xc_fun_section
369 : TYPE(sgp_potential_type), POINTER :: sgp_potential
370 32836 : TYPE(tau_basis_cache_type) :: tau_basis_cache
371 : TYPE(virial_type), POINTER :: virial
372 : TYPE(xc_derivative_set_type) :: deriv_set
373 : TYPE(xc_rho_cflags_type) :: needs
374 : TYPE(xc_rho_set_type) :: rho_set_h, rho_set_s, smooth_rho_set
375 :
376 : ! -------------------------------------------------------------------------
377 :
378 32836 : CALL timeset(routineN, handle)
379 :
380 32836 : NULLIFY (atom_list)
381 32836 : NULLIFY (auxbas_pw_pool)
382 32836 : NULLIFY (my_kind_set)
383 32836 : NULLIFY (atomic_kind_set)
384 32836 : NULLIFY (cell)
385 32836 : NULLIFY (grid_atom)
386 32836 : NULLIFY (gth_potential)
387 32836 : NULLIFY (force)
388 32836 : NULLIFY (harmonics)
389 32836 : NULLIFY (input)
390 32836 : NULLIFY (para_env)
391 32836 : NULLIFY (particle_set)
392 32836 : NULLIFY (pw_env)
393 32836 : NULLIFY (rho_atom)
394 32836 : NULLIFY (rho_struct)
395 32836 : NULLIFY (my_rho_atom_set)
396 32836 : NULLIFY (rho_nlcc)
397 32836 : NULLIFY (smooth_rho, smooth_rhoa, smooth_rhob, smooth_tau, smooth_tau_a, smooth_tau_b)
398 32836 : NULLIFY (composite_smooth_rho, composite_smooth_rhoa, composite_smooth_rhob, &
399 32836 : composite_smooth_tau, composite_smooth_tau_a, composite_smooth_tau_b)
400 32836 : NULLIFY (smooth_rho_g, smooth_rho_r, smooth_tau_r)
401 32836 : NULLIFY (smooth_vxc_rho, smooth_vxc_tau)
402 131344 : DO idir = 1, 3
403 98508 : NULLIFY (smooth_drho(idir)%array, smooth_drhoa(idir)%array, smooth_drhob(idir)%array)
404 : NULLIFY (composite_smooth_drho(idir)%array, &
405 98508 : composite_smooth_drhoa(idir)%array, &
406 131344 : composite_smooth_drhob(idir)%array)
407 : END DO
408 32836 : NULLIFY (sgp_potential)
409 32836 : NULLIFY (virial)
410 32836 : my_calculate_forces = .FALSE.
411 32836 : IF (PRESENT(calculate_forces)) my_calculate_forces = calculate_forces
412 32836 : IF (PRESENT(composite_reference_active)) composite_reference_active = .FALSE.
413 32836 : direct_valence_atom_composite = .FALSE.
414 32836 : IF (PRESENT(direct_valence_atom_grid)) THEN
415 136 : direct_valence_atom_composite = direct_valence_atom_grid
416 : END IF
417 32836 : requested_atom_composite_grid = .FALSE.
418 32836 : IF (PRESENT(atom_composite_grid)) requested_atom_composite_grid = atom_composite_grid
419 :
420 32836 : IF (PRESENT(adiabatic_rescale_factor)) THEN
421 44 : my_adiabatic_rescale_factor = adiabatic_rescale_factor
422 : ELSE
423 32792 : my_adiabatic_rescale_factor = 1.0_dp
424 : END IF
425 :
426 : CALL get_qs_env(qs_env=qs_env, &
427 : dft_control=dft_control, &
428 : cell=cell, &
429 : para_env=para_env, &
430 : atomic_kind_set=atomic_kind_set, &
431 : qs_kind_set=my_kind_set, &
432 : input=input, &
433 : particle_set=particle_set, &
434 : pw_env=pw_env, &
435 : virial=virial, &
436 : rho_atom_set=my_rho_atom_set, &
437 32836 : force=force)
438 :
439 32836 : IF (dft_control%qs_control%gapw_xc) THEN
440 5428 : CALL get_qs_env(qs_env=qs_env, rho_xc=rho_struct)
441 : ELSE
442 27408 : CALL get_qs_env(qs_env=qs_env, rho=rho_struct)
443 : END IF
444 :
445 32836 : IF (PRESENT(kind_set_external)) my_kind_set => kind_set_external
446 32836 : IF (PRESENT(rho_atom_set_external)) my_rho_atom_set => rho_atom_set_external
447 :
448 32836 : nlcc = has_nlcc(my_kind_set)
449 32836 : accint = dft_control%qs_control%gapw_control%accurate_xcint
450 :
451 32836 : my_xc_section => section_vals_get_subs_vals(input, "DFT%XC")
452 :
453 32836 : IF (PRESENT(xc_section_external)) my_xc_section => xc_section_external
454 :
455 32836 : xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
456 : CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
457 32836 : i_val=myfun)
458 32836 : skala_atom_grid = xc_section_uses_gauxc_model(my_xc_section)
459 32836 : gapw_representation = skala_gapw_cp2k_default
460 32836 : atom_composite_diagnostic = .FALSE.
461 32836 : atom_composite_reference = .FALSE.
462 32836 : paw_pseudopotentials = .FALSE.
463 32836 : native_grid_diagnostics = .FALSE.
464 32836 : atom_composite_components = 1
465 32836 : feature_vxc_step = 3.0E-3_dp
466 32836 : IF (skala_atom_grid) THEN
467 282 : gauxc_section => get_gauxc_section(my_xc_section)
468 282 : CPASSERT(ASSOCIATED(gauxc_section))
469 : CALL section_vals_val_get(gauxc_section, "PSEUDOPOTENTIAL_GAPW_REPRESENTATION", &
470 282 : i_val=gapw_representation)
471 : CALL section_vals_val_get(gauxc_section, "NATIVE_GRID_DIAGNOSTICS", &
472 282 : l_val=native_grid_diagnostics)
473 : END IF
474 : IF (skala_atom_grid) THEN
475 610 : DO ikind = 1, SIZE(my_kind_set)
476 328 : NULLIFY (gth_potential, sgp_potential)
477 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
478 328 : gth_potential=gth_potential, sgp_potential=sgp_potential)
479 : paw_pseudopotentials = paw_pseudopotentials .OR. &
480 : (paw_atom .AND. (ASSOCIATED(gth_potential) .OR. &
481 784 : ASSOCIATED(sgp_potential)))
482 : END DO
483 : END IF
484 32836 : IF (skala_atom_grid .AND. xc_section_uses_native_skala_evaluator(my_xc_section)) THEN
485 : CALL section_vals_val_get(gauxc_section, &
486 : "NATIVE_GRID_GAPW_ATOM_COMPOSITE_DIAGNOSTIC", &
487 280 : l_val=atom_composite_diagnostic)
488 : CALL section_vals_val_get(gauxc_section, &
489 : "NATIVE_GRID_GAPW_ATOM_COMPOSITE_REFERENCE", &
490 280 : l_val=atom_composite_reference)
491 : CALL section_vals_val_get(gauxc_section, &
492 : "NATIVE_GRID_GAPW_ATOM_COMPOSITE_COMPONENTS", &
493 280 : i_val=atom_composite_components)
494 : CALL section_vals_val_get(gauxc_section, &
495 : "NATIVE_GRID_GAPW_ATOM_COMPOSITE_FD_STEP", &
496 280 : r_val=feature_vxc_step)
497 : END IF
498 : atom_composite_reference = atom_composite_reference .OR. &
499 : (gapw_representation == skala_gapw_paw_one_center .AND. &
500 32836 : paw_pseudopotentials)
501 32836 : atom_composite_reference = atom_composite_reference .OR. requested_atom_composite_grid
502 32836 : atom_composite_reference = atom_composite_reference .OR. direct_valence_atom_composite
503 32836 : atom_composite_active = atom_composite_diagnostic .OR. atom_composite_reference
504 32836 : use_atom_composite_density = atom_composite_components <= 2
505 32836 : use_atom_composite_gradient = atom_composite_components <= 2
506 : use_atom_composite_tau = atom_composite_components == 1 .OR. &
507 32836 : atom_composite_components == 3
508 32836 : IF (atom_composite_active) THEN
509 264 : CALL ensure_native_skala_atom_grids(my_kind_set, dft_control)
510 : END IF
511 32836 : IF (direct_valence_atom_composite) THEN
512 136 : use_atom_composite_density = .FALSE.
513 136 : use_atom_composite_gradient = .FALSE.
514 136 : use_atom_composite_tau = .FALSE.
515 : END IF
516 : ! CP2K's auxiliary PW fields are represented on one index-periodic cell even
517 : ! when the physical Poisson problem is isolated or partially periodic.
518 32836 : image_partition_atom_composite = atom_composite_active
519 131344 : composite_image_periodicity = 1
520 32836 : IF (PRESENT(composite_reference_active)) composite_reference_active = atom_composite_reference
521 32836 : gapw_density_partition = skala_gapw_density_partition_hard_minus_soft
522 32836 : IF (skala_atom_grid) THEN
523 282 : gapw_density_partition = native_skala_gapw_density_partition(my_xc_section)
524 : END IF
525 32836 : use_virial = ASSOCIATED(virial)
526 32836 : IF (use_virial) use_virial = my_calculate_forces .AND. &
527 32836 : virial%pv_calculate .AND. (.NOT. virial%pv_numer)
528 :
529 32836 : IF (myfun == xc_none) THEN
530 4204 : exc1 = 0.0_dp
531 16442 : my_rho_atom_set(:)%exc_h = 0.0_dp
532 16442 : my_rho_atom_set(:)%exc_s = 0.0_dp
533 : ELSE
534 : CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
535 28632 : r_val=density_cut)
536 : CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
537 28632 : r_val=gradient_cut)
538 : CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
539 28632 : r_val=tau_cut)
540 :
541 28632 : lsd = dft_control%lsd
542 28632 : nspins = dft_control%nspins
543 : needs = xc_functionals_get_needs(xc_fun_section, &
544 : lsd=lsd, &
545 28632 : calc_potential=.TRUE.)
546 :
547 28632 : gradient_f = (needs%drho .OR. needs%drho_spin) .OR. skala_atom_grid
548 28632 : tau_f = (needs%tau .OR. needs%tau_spin) .OR. skala_atom_grid
549 :
550 28632 : IF (atom_composite_active) THEN
551 264 : IF (lsd) THEN
552 42 : needs%rho_spin = .TRUE.
553 42 : needs%drho_spin = .TRUE.
554 42 : needs%tau_spin = .TRUE.
555 : ELSE
556 222 : needs%rho = .TRUE.
557 222 : needs%drho = .TRUE.
558 222 : needs%tau = .TRUE.
559 : END IF
560 :
561 : ALLOCATE (composite_atomic_grid_sizes(SIZE(particle_set)), &
562 0 : composite_atom_kind(SIZE(particle_set)), &
563 : composite_atom_kind_index(SIZE(particle_set)), &
564 0 : composite_atom_start(SIZE(particle_set)), &
565 0 : composite_atom_end(SIZE(particle_set)), &
566 0 : composite_atom_coords(3, SIZE(particle_set)), &
567 0 : composite_partition_weights(SIZE(particle_set)), &
568 0 : composite_partition_atom_coords(3, SIZE(particle_set)), &
569 3432 : composite_distances(SIZE(particle_set)))
570 264 : composite_atomic_grid_sizes = 0_int_8
571 264 : composite_atom_kind = 0
572 264 : composite_atom_kind_index = 0
573 264 : composite_atom_start = 0
574 264 : composite_atom_end = 0
575 794 : DO iatom = 1, SIZE(particle_set)
576 2384 : composite_atom_coords(:, iatom) = particle_set(iatom)%r
577 : END DO
578 574 : DO ikind = 1, SIZE(atomic_kind_set)
579 310 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
580 310 : NULLIFY (gth_potential, sgp_potential)
581 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
582 : gth_potential=gth_potential, grid_atom=grid_atom, &
583 310 : sgp_potential=sgp_potential, zatom=zatom, zeff=zeff)
584 1104 : DO iat = 1, natom
585 530 : iatom = atom_list(iat)
586 530 : composite_atomic_grid_sizes(iatom) = INT(grid_atom%nr*grid_atom%ng_sphere, KIND=int_8)
587 530 : composite_atom_kind(iatom) = ikind
588 840 : composite_atom_kind_index(iatom) = iat
589 : END DO
590 : END DO
591 794 : IF (ANY(composite_atomic_grid_sizes <= 0_int_8)) THEN
592 : CALL cp_abort(__LOCATION__, &
593 0 : "The atom-composite diagnostic requires a GAPW one-center grid for every atom.")
594 : END IF
595 :
596 264 : composite_local_natom = 0
597 574 : DO ikind = 1, SIZE(atomic_kind_set)
598 310 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
599 310 : NULLIFY (gth_potential, sgp_potential)
600 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
601 : gth_potential=gth_potential, sgp_potential=sgp_potential, &
602 310 : zatom=zatom, zeff=zeff)
603 310 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
604 884 : composite_local_natom = composite_local_natom + MAX(0, bo(2) - bo(1) + 1)
605 : END DO
606 0 : ALLOCATE (composite_local_atoms(composite_local_natom), &
607 0 : composite_local_grid_sizes(composite_local_natom), &
608 1782 : composite_local_atom_coords(3, composite_local_natom))
609 264 : composite_local_atom = 0
610 264 : composite_nflat = 0
611 574 : DO ikind = 1, SIZE(atomic_kind_set)
612 310 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
613 310 : NULLIFY (gth_potential, sgp_potential)
614 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
615 : gth_potential=gth_potential, sgp_potential=sgp_potential, &
616 310 : zatom=zatom, zeff=zeff)
617 310 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
618 1149 : DO iat = bo(1), bo(2)
619 265 : iatom = atom_list(iat)
620 265 : composite_local_atom = composite_local_atom + 1
621 265 : composite_local_atoms(composite_local_atom) = iatom
622 : composite_local_grid_sizes(composite_local_atom) = &
623 265 : composite_atomic_grid_sizes(iatom)
624 : composite_local_atom_coords(:, composite_local_atom) = &
625 1060 : composite_atom_coords(:, iatom)
626 265 : composite_atom_start(iatom) = composite_nflat + 1
627 265 : composite_nflat = composite_nflat + INT(composite_atomic_grid_sizes(iatom))
628 575 : composite_atom_end(iatom) = composite_nflat
629 : END DO
630 : END DO
631 264 : CPASSERT(composite_local_atom == composite_local_natom)
632 0 : ALLOCATE (composite_density(composite_nflat, 2), &
633 0 : composite_grad(composite_nflat, 3, 2), &
634 0 : composite_kin(composite_nflat, 2), &
635 0 : composite_grid_atom(composite_nflat), &
636 0 : composite_smooth_density_cache(composite_nflat, 2), &
637 0 : composite_smooth_gradient_cache(composite_nflat, 3, 2), &
638 0 : composite_smooth_kin_cache(composite_nflat, 2), &
639 0 : composite_grid_coords(3, composite_nflat), &
640 0 : composite_grid_weights(composite_nflat), &
641 0 : composite_base_grid_weights(composite_nflat), &
642 4510 : composite_atomic_grid_weights(composite_nflat))
643 264 : composite_density = 0.0_dp
644 264 : composite_grad = 0.0_dp
645 264 : composite_kin = 0.0_dp
646 529 : DO composite_local_atom = 1, composite_local_natom
647 265 : iatom = composite_local_atoms(composite_local_atom)
648 458789 : composite_grid_atom(composite_atom_start(iatom):composite_atom_end(iatom)) = iatom
649 : END DO
650 264 : composite_smooth_density_cache = 0.0_dp
651 264 : composite_smooth_gradient_cache = 0.0_dp
652 264 : composite_smooth_kin_cache = 0.0_dp
653 264 : composite_grid_coords = 0.0_dp
654 264 : composite_grid_weights = 0.0_dp
655 264 : composite_base_grid_weights = 0.0_dp
656 264 : composite_atomic_grid_weights = 0.0_dp
657 :
658 : CALL qs_rho_get(rho_struct, rho_r=smooth_rho_r, rho_g=smooth_rho_g, &
659 : tau_r=smooth_tau_r, rho_g_valid=rho_g_valid, &
660 264 : tau_r_valid=tau_r_valid)
661 264 : CPASSERT(rho_g_valid)
662 264 : CPASSERT(tau_r_valid)
663 264 : CPASSERT(ASSOCIATED(smooth_rho_r))
664 264 : CPASSERT(ASSOCIATED(smooth_rho_g))
665 264 : CPASSERT(ASSOCIATED(smooth_tau_r))
666 : CALL prepare_native_grid_cache(qs_env%native_grid_cache, smooth_rho_r(1)%pw_grid, &
667 264 : cell, composite_nflat, image_partition_atom_composite)
668 264 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
669 : CALL section_vals_val_get(my_xc_section, "XC_GRID%XC_DERIV", &
670 264 : i_val=xc_deriv_method_id)
671 : CALL section_vals_val_get(my_xc_section, "XC_GRID%XC_SMOOTH_RHO", &
672 264 : i_val=xc_rho_smooth_id)
673 : CALL xc_rho_set_create(smooth_rho_set, smooth_rho_r(1)%pw_grid%bounds_local, &
674 : rho_cutoff=section_get_rval(my_xc_section, "density_cutoff"), &
675 : drho_cutoff=section_get_rval(my_xc_section, "gradient_cutoff"), &
676 264 : tau_cutoff=section_get_rval(my_xc_section, "tau_cutoff"))
677 : CALL xc_rho_set_update(smooth_rho_set, smooth_rho_r, smooth_rho_g, smooth_tau_r, needs, &
678 264 : xc_deriv_method_id, xc_rho_smooth_id, auxbas_pw_pool)
679 792 : IF (lsd) THEN
680 : CALL xc_rho_set_get(smooth_rho_set, rhoa=smooth_rhoa, rhob=smooth_rhob, &
681 : drhoa=smooth_drhoa, drhob=smooth_drhob, &
682 42 : tau_a=smooth_tau_a, tau_b=smooth_tau_b)
683 : CALL gather_native_grid_field(smooth_rhoa, smooth_rho_r(1)%pw_grid, para_env, &
684 42 : composite_smooth_rhoa)
685 : CALL gather_native_grid_field(smooth_rhob, smooth_rho_r(1)%pw_grid, para_env, &
686 42 : composite_smooth_rhob)
687 : CALL gather_native_grid_field(smooth_tau_a, smooth_rho_r(1)%pw_grid, para_env, &
688 42 : composite_smooth_tau_a)
689 : CALL gather_native_grid_field(smooth_tau_b, smooth_rho_r(1)%pw_grid, para_env, &
690 42 : composite_smooth_tau_b)
691 168 : DO idir = 1, 3
692 : CALL gather_native_grid_field(smooth_drhoa(idir)%array, &
693 : smooth_rho_r(1)%pw_grid, para_env, &
694 126 : composite_smooth_drhoa(idir)%array)
695 : CALL gather_native_grid_field(smooth_drhob(idir)%array, &
696 : smooth_rho_r(1)%pw_grid, para_env, &
697 168 : composite_smooth_drhob(idir)%array)
698 : END DO
699 : ELSE
700 : CALL xc_rho_set_get(smooth_rho_set, rho=smooth_rho, drho=smooth_drho, &
701 222 : tau=smooth_tau)
702 : CALL gather_native_grid_field(smooth_rho, smooth_rho_r(1)%pw_grid, para_env, &
703 222 : composite_smooth_rho)
704 : CALL gather_native_grid_field(smooth_tau, smooth_rho_r(1)%pw_grid, para_env, &
705 222 : composite_smooth_tau)
706 888 : DO idir = 1, 3
707 : CALL gather_native_grid_field(smooth_drho(idir)%array, &
708 : smooth_rho_r(1)%pw_grid, para_env, &
709 888 : composite_smooth_drho(idir)%array)
710 : END DO
711 : END IF
712 : END IF
713 :
714 : ! Initialize energy contribution from the one center XC terms to zero
715 28632 : exc1 = 0.0_dp
716 :
717 : ! Nullify some pointers for work-arrays
718 28632 : NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
719 28632 : NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
720 28632 : NULLIFY (tau_h, tau_s)
721 28632 : NULLIFY (vtau_h, vtau_s)
722 :
723 : ! Here starts the loop over all the atoms
724 :
725 83980 : DO ikind = 1, SIZE(atomic_kind_set)
726 55348 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
727 55348 : NULLIFY (gth_potential, sgp_potential)
728 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
729 : gth_potential=gth_potential, harmonics=harmonics, &
730 : grid_atom=grid_atom, sgp_potential=sgp_potential, &
731 55348 : zatom=zatom, zeff=zeff)
732 55348 : one_center_kind = .NOT. direct_valence_atom_composite
733 55348 : IF (one_center_kind) THEN
734 55202 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
735 55202 : one_center_kind = paw_atom
736 55202 : IF (skala_atom_grid) THEN
737 : one_center_kind = native_skala_uses_one_center_kind( &
738 : paw_atom, gapw_representation, &
739 : ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
740 206 : zeff, zatom)
741 : END IF
742 : END IF
743 55348 : IF (.NOT. one_center_kind .AND. .NOT. atom_composite_active) CYCLE
744 :
745 49928 : nr = grid_atom%nr
746 49928 : na = grid_atom%ng_sphere
747 :
748 49928 : IF (one_center_kind) THEN
749 : ! Prepare the structures needed to calculate and store the one-center XC derivatives.
750 :
751 : ! Array dimension: here anly one dimensional arrays are used,
752 : ! i.e. only the first column of deriv_data is read.
753 : ! The other to dimensions are set to size equal 1
754 497780 : bounds(1:2, 1:3) = 1
755 49778 : bounds(2, 1) = na
756 49778 : bounds(2, 2) = nr
757 :
758 : ! set integration weights
759 49778 : IF (accint) THEN
760 14748 : weight_h => grid_atom%weight
761 14748 : alpha = dft_control%qs_control%gapw_control%aw(ikind)
762 14748 : IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
763 14216 : IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
764 : END IF
765 14748 : IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
766 2128 : ALLOCATE (grid_atom%gapw_weight_s(na, nr))
767 26952 : DO ir = 1, nr
768 26420 : agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
769 1343632 : grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
770 : END DO
771 532 : grid_atom%gapw_weight_alpha = alpha
772 : END IF
773 14748 : weight_s => grid_atom%gapw_weight_s
774 : ELSE
775 35030 : weight_h => grid_atom%weight
776 35030 : weight_s => grid_atom%weight
777 : END IF
778 :
779 : ! create a place where to put the derivatives
780 49778 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
781 : ! create the place where to store the argument for the functionals
782 : CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
783 49778 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
784 : CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
785 49778 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
786 :
787 : ! allocate the required 3d arrays where to store rho and drho
788 49778 : CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
789 49778 : CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
790 :
791 49778 : CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
792 49778 : CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
793 49778 : CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
794 49778 : CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
795 : !
796 49778 : IF (gradient_f) THEN
797 33262 : CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
798 33262 : CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
799 33262 : CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
800 33262 : CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
801 : END IF
802 :
803 49778 : IF (tau_f) THEN
804 1328 : CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
805 1328 : CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
806 1328 : CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
807 1328 : CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
808 1328 : CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
809 : END IF
810 :
811 : ! NLCC for separate hard and soft one-center densities.
812 49778 : donlcc = .FALSE.
813 49778 : IF (nlcc) THEN
814 1138 : NULLIFY (rho_nlcc)
815 1138 : rho_nlcc => my_kind_set(ikind)%nlcc_pot
816 1138 : IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
817 : END IF
818 : END IF
819 :
820 : ! Distribute the atoms of this kind
821 :
822 49928 : num_pe = para_env%num_pe
823 49928 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
824 :
825 88822 : DO iat = bo(1), bo(2)
826 38894 : iatom = atom_list(iat)
827 :
828 38894 : IF (one_center_kind) THEN
829 38755 : my_rho_atom_set(iatom)%exc_h = 0.0_dp
830 38755 : my_rho_atom_set(iatom)%exc_s = 0.0_dp
831 :
832 38755 : rho_atom => my_rho_atom_set(iatom)
833 125043140 : rho_h = 0.0_dp
834 125043140 : rho_s = 0.0_dp
835 38755 : IF (gradient_f) THEN
836 25235 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
837 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
838 : rho_rad_s=r_s, drho_rad_h=dr_h, &
839 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
840 25235 : rho_rad_s_d=r_s_d)
841 368849098 : drho_h = 0.0_dp
842 368849098 : drho_s = 0.0_dp
843 : ELSE
844 13520 : NULLIFY (r_h, r_s)
845 13520 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
846 13520 : rho_d = 0.0_dp
847 : END IF
848 38755 : IF (tau_f) THEN
849 938 : CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
850 : ELSE
851 37817 : tau_d = 0.0_dp
852 : END IF
853 :
854 2144345 : DO ir = 1, nr
855 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
856 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
857 2105590 : r_h_d, r_s_d, drho_h, drho_s)
858 2144345 : IF (donlcc) THEN
859 : CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
860 : ir, rho_nlcc(:, 1), rho_h, rho_s, &
861 17150 : rho_nlcc(:, 2), drho_h, drho_s)
862 : END IF
863 : END DO
864 : END IF
865 :
866 38894 : IF (atom_composite_active) THEN
867 265 : IF (image_partition_atom_composite) THEN
868 : CALL build_periodic_atom_image_layout( &
869 : composite_atom_coords, cell, iatom, composite_image_periodicity, &
870 265 : composite_partition_image_coords, composite_partition_target_image)
871 : CALL build_periodic_atom_image_layout( &
872 : composite_atom_coords(:, iatom:iatom), cell, 1, &
873 : composite_image_periodicity, composite_descriptor_image_coords, &
874 265 : composite_descriptor_target_image)
875 : END IF
876 : !$OMP PARALLEL DO COLLAPSE(2) IF (image_partition_atom_composite) SCHEDULE(STATIC) DEFAULT(NONE) &
877 : !$OMP PRIVATE(composite_row, composite_point, composite_smooth_density_value, &
878 : !$OMP composite_smooth_gradient_value, composite_smooth_kin_value, &
879 : !$OMP descriptor_window_weight, idir, ispin, &
880 : !$OMP gth_potential, nlcc_density, nlcc_gradient, nlcc_hessian, nlcc_spin_factor, &
881 : !$OMP interpolation_stencil, partition_scale, partition_weight, sgp_potential, source_atom) &
882 : !$OMP SHARED(atom_composite_reference, cell, composite_atom_coords, composite_atom_kind, &
883 : !$OMP composite_atom_start, composite_atomic_grid_weights, composite_base_grid_weights, &
884 : !$OMP composite_density, composite_descriptor_image_coords, &
885 : !$OMP composite_descriptor_target_image, composite_distances, composite_grad, &
886 : !$OMP composite_grid_coords, composite_grid_weights, composite_kin, &
887 : !$OMP composite_partition_atom_coords, composite_partition_image_coords, &
888 : !$OMP composite_partition_target_image, composite_partition_weights, &
889 : !$OMP composite_smooth_density_cache, composite_smooth_drho, composite_smooth_drhoa, &
890 : !$OMP composite_smooth_drhob, composite_smooth_gradient_cache, &
891 : !$OMP composite_smooth_kin_cache, composite_smooth_rho, composite_smooth_rhoa, &
892 : !$OMP composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
893 : !$OMP composite_smooth_tau_b, drho_h, drho_s, grid_atom, iatom, &
894 : !$OMP image_partition_atom_composite, lsd, my_kind_set, na, nlcc, nr, one_center_kind, &
895 : !$OMP particle_set, qs_env, rho_h, rho_s, smooth_rho_r, tau_h, tau_s, &
896 265 : !$OMP use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau)
897 : DO ir = 1, nr
898 : DO ia = 1, na
899 : composite_row = composite_atom_start(iatom) + (ir - 1)*na + ia - 1
900 : composite_point(1) = particle_set(iatom)%r(1) + grid_atom%rad(ir)* &
901 : grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
902 : composite_point(2) = particle_set(iatom)%r(2) + grid_atom%rad(ir)* &
903 : grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
904 : composite_point(3) = particle_set(iatom)%r(3) + &
905 : grid_atom%rad(ir)*grid_atom%cos_pol(ia)
906 : composite_grid_coords(:, composite_row) = composite_point
907 : IF (image_partition_atom_composite) THEN
908 : CALL periodic_atom_image_partition_from_layout( &
909 : composite_point, composite_partition_image_coords, &
910 : composite_partition_target_image, partition_weight)
911 : ! The self-image partition defines a smooth atom-centered periodic
912 : ! descriptor domain without truncating it at neighboring atoms.
913 : CALL periodic_atom_image_partition_from_layout( &
914 : composite_point, composite_descriptor_image_coords, &
915 : composite_descriptor_target_image, descriptor_window_weight)
916 : partition_scale = smooth_partition_atomic_weight_scale( &
917 : descriptor_window_weight)
918 : ELSE
919 : CALL smooth_atom_partition( &
920 : composite_point, composite_atom_coords, cell, &
921 : composite_partition_weights, composite_partition_atom_coords, &
922 : composite_distances)
923 : partition_weight = composite_partition_weights(iatom)
924 : partition_scale = 1.0_dp
925 : END IF
926 : composite_base_grid_weights(composite_row) = grid_atom%weight(ia, ir)
927 : composite_atomic_grid_weights(composite_row) = &
928 : composite_base_grid_weights(composite_row)*partition_scale
929 : composite_grid_weights(composite_row) = &
930 : composite_base_grid_weights(composite_row)* &
931 : partition_weight
932 : IF (.NOT. fetch_native_grid_stencil(qs_env%native_grid_cache, composite_row, &
933 : composite_point, interpolation_stencil)) THEN
934 : CALL create_native_grid_interpolation_stencil( &
935 : interpolation_stencil, smooth_rho_r(1)%pw_grid, cell, composite_point, &
936 : image_partition_atom_composite)
937 : CALL store_native_grid_stencil(qs_env%native_grid_cache, composite_row, &
938 : composite_point, interpolation_stencil)
939 : END IF
940 : IF (lsd) THEN
941 : CALL interpolate_native_grid_fields( &
942 : composite_smooth_rhoa, composite_smooth_drhoa(1)%array, &
943 : composite_smooth_drhoa(2)%array, composite_smooth_drhoa(3)%array, &
944 : composite_smooth_tau_a, interpolation_stencil, &
945 : composite_smooth_density_value(1), &
946 : composite_smooth_gradient_value(:, 1), &
947 : composite_smooth_kin_value(1))
948 : CALL interpolate_native_grid_fields( &
949 : composite_smooth_rhob, composite_smooth_drhob(1)%array, &
950 : composite_smooth_drhob(2)%array, composite_smooth_drhob(3)%array, &
951 : composite_smooth_tau_b, interpolation_stencil, &
952 : composite_smooth_density_value(2), &
953 : composite_smooth_gradient_value(:, 2), &
954 : composite_smooth_kin_value(2))
955 : composite_smooth_density_cache(composite_row, :) = &
956 : composite_smooth_density_value
957 : composite_smooth_gradient_cache(composite_row, :, :) = &
958 : composite_smooth_gradient_value
959 : composite_smooth_kin_cache(composite_row, :) = &
960 : composite_smooth_kin_value
961 : DO ispin = 1, 2
962 : composite_density(composite_row, ispin) = &
963 : composite_smooth_density_value(ispin)
964 : composite_grad(composite_row, :, ispin) = &
965 : composite_smooth_gradient_value(:, ispin)
966 : composite_kin(composite_row, ispin) = &
967 : composite_smooth_kin_value(ispin)
968 : IF (one_center_kind .AND. use_atom_composite_density) THEN
969 : composite_density(composite_row, ispin) = &
970 : composite_density(composite_row, ispin) + &
971 : rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin)
972 : END IF
973 : IF (one_center_kind .AND. use_atom_composite_gradient) THEN
974 : DO idir = 1, 3
975 : composite_grad(composite_row, idir, ispin) = &
976 : composite_grad(composite_row, idir, ispin) + &
977 : drho_h(idir, ia, ir, ispin) - drho_s(idir, ia, ir, ispin)
978 : END DO
979 : END IF
980 : IF (one_center_kind .AND. use_atom_composite_tau) THEN
981 : composite_kin(composite_row, ispin) = &
982 : composite_kin(composite_row, ispin) + &
983 : tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin)
984 : END IF
985 : END DO
986 : ELSE
987 : CALL interpolate_native_grid_fields( &
988 : composite_smooth_rho, composite_smooth_drho(1)%array, &
989 : composite_smooth_drho(2)%array, composite_smooth_drho(3)%array, &
990 : composite_smooth_tau, interpolation_stencil, &
991 : composite_smooth_density_value(1), &
992 : composite_smooth_gradient_value(:, 1), &
993 : composite_smooth_kin_value(1))
994 : composite_smooth_density_cache(composite_row, 1) = &
995 : composite_smooth_density_value(1)
996 : composite_smooth_gradient_cache(composite_row, :, 1) = &
997 : composite_smooth_gradient_value(:, 1)
998 : composite_smooth_kin_cache(composite_row, 1) = &
999 : composite_smooth_kin_value(1)
1000 : composite_density(composite_row, :) = &
1001 : 0.5_dp*composite_smooth_density_value(1)
1002 : DO idir = 1, 3
1003 : composite_grad(composite_row, idir, :) = &
1004 : 0.5_dp*composite_smooth_gradient_value(idir, 1)
1005 : END DO
1006 : composite_kin(composite_row, :) = &
1007 : 0.5_dp*composite_smooth_kin_value(1)
1008 : IF (one_center_kind .AND. use_atom_composite_density) THEN
1009 : composite_density(composite_row, :) = &
1010 : composite_density(composite_row, :) + &
1011 : 0.5_dp*(rho_h(ia, ir, 1) - rho_s(ia, ir, 1))
1012 : END IF
1013 : IF (one_center_kind .AND. use_atom_composite_gradient) THEN
1014 : DO idir = 1, 3
1015 : composite_grad(composite_row, idir, :) = &
1016 : composite_grad(composite_row, idir, :) + &
1017 : 0.5_dp*(drho_h(idir, ia, ir, 1) - &
1018 : drho_s(idir, ia, ir, 1))
1019 : END DO
1020 : END IF
1021 : IF (one_center_kind .AND. use_atom_composite_tau) THEN
1022 : composite_kin(composite_row, :) = composite_kin(composite_row, :) + &
1023 : 0.5_dp*(tau_h(ia, ir, 1) - &
1024 : tau_s(ia, ir, 1))
1025 : END IF
1026 : END IF
1027 : IF (atom_composite_reference .AND. nlcc) THEN
1028 : nlcc_spin_factor = MERGE(1.0_dp, 0.5_dp, lsd)
1029 : DO source_atom = 1, SIZE(particle_set)
1030 : NULLIFY (gth_potential, sgp_potential)
1031 : CALL get_qs_kind(my_kind_set(composite_atom_kind(source_atom)), &
1032 : gth_potential=gth_potential, &
1033 : sgp_potential=sgp_potential)
1034 : CALL evaluate_nlcc_primitive_fields( &
1035 : composite_point, particle_set(source_atom)%r, &
1036 : gth_potential, sgp_potential, nlcc_density, &
1037 : nlcc_gradient, nlcc_hessian)
1038 : composite_density(composite_row, :) = &
1039 : composite_density(composite_row, :) + &
1040 : nlcc_spin_factor*nlcc_density
1041 : DO idir = 1, 3
1042 : composite_grad(composite_row, idir, :) = &
1043 : composite_grad(composite_row, idir, :) + &
1044 : nlcc_spin_factor*nlcc_gradient(idir)
1045 : END DO
1046 : END DO
1047 : END IF
1048 : END DO
1049 : END DO
1050 : !$OMP END PARALLEL DO
1051 265 : IF (image_partition_atom_composite) THEN
1052 265 : DEALLOCATE (composite_descriptor_image_coords, composite_partition_image_coords)
1053 : END IF
1054 265 : CPASSERT(nr*na == composite_atom_end(iatom) - composite_atom_start(iatom) + 1)
1055 : END IF
1056 :
1057 38894 : IF (.NOT. one_center_kind) CYCLE
1058 :
1059 2144345 : DO ir = 1, nr
1060 2144345 : IF (tau_f) THEN
1061 45500 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
1062 45500 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
1063 2060090 : ELSE IF (gradient_f) THEN
1064 1230990 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
1065 1230990 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
1066 : ELSE
1067 829100 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
1068 829100 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
1069 : END IF
1070 : END DO
1071 :
1072 38755 : evaluate_hard = .TRUE.
1073 38755 : evaluate_soft = .TRUE.
1074 38755 : skala_atom_force_h = 0.0_dp
1075 38755 : skala_atom_force_s = 0.0_dp
1076 38755 : skala_atom_virial_h = 0.0_dp
1077 38755 : skala_atom_virial_s = 0.0_dp
1078 38755 : IF (skala_atom_grid) THEN
1079 : SELECT CASE (gapw_density_partition)
1080 : CASE (skala_gapw_density_partition_hard_minus_soft)
1081 0 : CONTINUE
1082 : CASE (skala_gapw_density_partition_hard_only)
1083 0 : evaluate_soft = .FALSE.
1084 : CASE (skala_gapw_density_partition_soft_only)
1085 0 : evaluate_hard = .FALSE.
1086 : CASE (skala_gapw_density_partition_none)
1087 0 : evaluate_hard = .FALSE.
1088 0 : evaluate_soft = .FALSE.
1089 : CASE DEFAULT
1090 : CALL cp_abort(__LOCATION__, &
1091 128 : "Unknown GAUXC%NATIVE_GRID_GAPW_DENSITY_PARTITION value.")
1092 : END SELECT
1093 : END IF
1094 38755 : IF (atom_composite_reference) THEN
1095 126 : evaluate_hard = .FALSE.
1096 126 : evaluate_soft = .FALSE.
1097 : END IF
1098 :
1099 : !-------------------!
1100 : ! hard atom density !
1101 : !-------------------!
1102 38755 : CALL xc_dset_zero_all(deriv_set)
1103 38755 : IF (.NOT. evaluate_hard) THEN
1104 126 : exc_h = 0.0_dp
1105 126 : IF (.NOT. energy_only) THEN
1106 119052 : vxc_h = 0.0_dp
1107 464652 : IF (ASSOCIATED(vxg_h)) vxg_h = 0.0_dp
1108 119052 : IF (ASSOCIATED(vtau_h)) vtau_h = 0.0_dp
1109 : END IF
1110 38629 : ELSE IF (skala_atom_grid) THEN
1111 : CALL skala_gapw_atom_vxc_of_r( &
1112 : my_xc_section, grid_atom, para_env, particle_set(iatom)%r, &
1113 : rho_h, drho_h, tau_h, weight_h, lsd, nspins, na, nr, &
1114 : exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
1115 2 : atom_force=skala_atom_force_h, atom_virial=skala_atom_virial_h)
1116 : ELSE
1117 : CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
1118 : lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
1119 38627 : adiabatic_rescale_factor=my_adiabatic_rescale_factor)
1120 : END IF
1121 38755 : rho_atom%exc_h = rho_atom%exc_h + exc_h
1122 :
1123 : !-------------------!
1124 : ! soft atom density !
1125 : !-------------------!
1126 38755 : CALL xc_dset_zero_all(deriv_set)
1127 38755 : IF (.NOT. evaluate_soft) THEN
1128 126 : exc_s = 0.0_dp
1129 126 : IF (.NOT. energy_only) THEN
1130 119052 : vxc_s = 0.0_dp
1131 464652 : IF (ASSOCIATED(vxg_s)) vxg_s = 0.0_dp
1132 119052 : IF (ASSOCIATED(vtau_s)) vtau_s = 0.0_dp
1133 : END IF
1134 38629 : ELSE IF (skala_atom_grid) THEN
1135 : CALL skala_gapw_atom_vxc_of_r( &
1136 : my_xc_section, grid_atom, para_env, particle_set(iatom)%r, &
1137 : rho_s, drho_s, tau_s, weight_s, lsd, nspins, na, nr, &
1138 : exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
1139 2 : atom_force=skala_atom_force_s, atom_virial=skala_atom_virial_s)
1140 : ELSE
1141 : CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
1142 : lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
1143 38627 : adiabatic_rescale_factor=my_adiabatic_rescale_factor)
1144 : END IF
1145 38755 : rho_atom%exc_s = rho_atom%exc_s + exc_s
1146 :
1147 : ! Add contributions to the exc energy
1148 :
1149 38755 : exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
1150 38755 : IF (skala_atom_grid .AND. my_calculate_forces .AND. ASSOCIATED(force)) THEN
1151 : force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
1152 140 : skala_atom_force_h - skala_atom_force_s
1153 : END IF
1154 38755 : IF (skala_atom_grid .AND. use_virial) THEN
1155 403 : skala_atom_virial = skala_atom_virial_h - skala_atom_virial_s
1156 124 : DO idir = 1, 3
1157 403 : DO jdir = 1, 3
1158 : virial%pv_gapw(idir, jdir) = virial%pv_gapw(idir, jdir) + &
1159 279 : skala_atom_virial(idir, jdir)
1160 : virial%pv_virial(idir, jdir) = virial%pv_virial(idir, jdir) + &
1161 372 : skala_atom_virial(idir, jdir)
1162 : END DO
1163 : END DO
1164 : END IF
1165 :
1166 : ! Integration to get the matrix elements relative to the vxc_atom
1167 : ! here the products with the primitives is done: gaVxcgb
1168 : ! internal transformation to get the integral in cartesian Gaussians
1169 :
1170 38755 : IF (.NOT. energy_only) THEN
1171 37119 : NULLIFY (int_hh, int_ss)
1172 37119 : CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
1173 37119 : IF (gradient_f) THEN
1174 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
1175 23763 : grid_atom, basis_1c, harmonics, nspins)
1176 : ELSE
1177 : CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
1178 13356 : grid_atom, basis_1c, harmonics, nspins)
1179 : END IF
1180 37119 : IF (tau_f) THEN
1181 938 : CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, tau_basis_cache, nspins)
1182 : END IF
1183 : END IF ! energy_only
1184 88822 : NULLIFY (r_h, r_s, dr_h, dr_s)
1185 : END DO ! iat
1186 :
1187 133908 : IF (one_center_kind) THEN
1188 49778 : IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
1189 :
1190 49778 : CALL xc_dset_release(deriv_set)
1191 49778 : CALL xc_rho_set_release(rho_set_h)
1192 49778 : CALL xc_rho_set_release(rho_set_s)
1193 : END IF
1194 : END DO ! ikind
1195 :
1196 28632 : IF (atom_composite_active) THEN
1197 0 : ALLOCATE (composite_cross_density(composite_nflat, 2), &
1198 0 : composite_cross_grad(composite_nflat, 3, 2), &
1199 1782 : composite_cross_kin(composite_nflat, 2))
1200 264 : composite_cross_density = 0.0_dp
1201 264 : composite_cross_grad = 0.0_dp
1202 264 : composite_cross_kin = 0.0_dp
1203 264 : composite_cross_cutoff_max = 0.0_dp
1204 264 : IF (.NOT. direct_valence_atom_composite) THEN
1205 292 : DO ikind = 1, SIZE(atomic_kind_set)
1206 164 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
1207 164 : NULLIFY (gth_potential, sgp_potential)
1208 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
1209 : gth_potential=gth_potential, harmonics=harmonics, &
1210 : grid_atom=grid_atom, sgp_potential=sgp_potential, &
1211 164 : zatom=zatom, zeff=zeff)
1212 164 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
1213 188 : IF (.NOT. native_skala_uses_one_center_kind( &
1214 : paw_atom, gapw_representation, &
1215 : ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
1216 : zeff, zatom)) CYCLE
1217 :
1218 : CALL replicate_rho_atom_radial( &
1219 160 : para_env, my_rho_atom_set, my_kind_set(ikind), atom_list, natom, nspins)
1220 160 : nr = grid_atom%nr
1221 160 : na = grid_atom%ng_sphere
1222 160 : CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
1223 160 : CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
1224 160 : CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
1225 160 : CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
1226 160 : CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
1227 160 : CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
1228 160 : CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
1229 :
1230 : ! The one-center density matrices are already globally reduced. Distribute the
1231 : ! overlap work by target atom so that every rank constructs only its model rows.
1232 412 : DO iat = 1, natom
1233 252 : source_atom = atom_list(iat)
1234 252 : rho_atom => my_rho_atom_set(source_atom)
1235 252 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
1236 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s, &
1237 : drho_rad_h=dr_h, drho_rad_s=dr_s, &
1238 252 : rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
1239 238104 : rho_h = 0.0_dp
1240 238104 : rho_s = 0.0_dp
1241 1159704 : drho_h = 0.0_dp
1242 1159704 : drho_s = 0.0_dp
1243 252 : CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
1244 7452 : DO ir = 1, nr
1245 : CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
1246 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
1247 7452 : r_h_d, r_s_d, drho_h, drho_s)
1248 : END DO
1249 :
1250 : cross_cutoff = gapw_atom_grid_support_radius( &
1251 252 : grid_atom, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s)
1252 252 : IF (cross_cutoff <= 0.0_dp) CYCLE
1253 228 : composite_cross_cutoff_max = MAX(composite_cross_cutoff_max, cross_cutoff)
1254 228 : image_shell = 0
1255 912 : DO idir = 1, 3
1256 912 : IF (cell%perd(idir) == 1) THEN
1257 : image_shell(idir) = CEILING( &
1258 2544 : cross_cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))) + 1
1259 : END IF
1260 : END DO
1261 :
1262 : !$OMP PARALLEL DO DEFAULT(NONE) SCHEDULE(STATIC) &
1263 : !$OMP PRIVATE(image_lower, image_upper, composite_row, cross_density, cross_density_spatial, &
1264 : !$OMP cross_displacement, cross_grad, cross_grad_spatial, cross_kin, &
1265 : !$OMP cross_kin_spatial, fractional, idir, image_i1, image_i2, image_i3, jdir, &
1266 : !$OMP image_shift, image_translation, target_atom) &
1267 : !$OMP SHARED(cell, composite_cross_density, composite_cross_grad, composite_cross_kin, &
1268 : !$OMP composite_grid_atom, composite_grid_coords, composite_nflat, cross_cutoff, &
1269 : !$OMP drho_h, drho_s, grid_atom, harmonics, image_shell, lsd, nspins, &
1270 : !$OMP particle_set, rho_h, rho_s, source_atom, tau_h, tau_s, &
1271 412 : !$OMP use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau)
1272 : DO composite_row = 1, composite_nflat
1273 : target_atom = composite_grid_atom(composite_row)
1274 : fractional = 0.0_dp
1275 : DO idir = 1, 3
1276 : DO jdir = 1, 3
1277 : fractional(idir) = fractional(idir) + cell%h_inv(idir, jdir)* &
1278 : (composite_grid_coords(jdir, composite_row) - &
1279 : particle_set(source_atom)%r(jdir))
1280 : END DO
1281 : END DO
1282 : CALL atom_grid_image_bounds(cell, fractional, cross_cutoff, image_shell, &
1283 : image_lower, image_upper)
1284 : DO image_i3 = image_lower(3), image_upper(3)
1285 : DO image_i2 = image_lower(2), image_upper(2)
1286 : DO image_i1 = image_lower(1), image_upper(1)
1287 : image_shift = [image_i1, image_i2, image_i3]
1288 : IF (target_atom == source_atom .AND. &
1289 : ALL(image_shift == 0)) CYCLE
1290 : image_translation = MATMUL( &
1291 : cell%hmat, REAL(image_shift, dp))
1292 : cross_displacement = composite_grid_coords(:, composite_row) - &
1293 : particle_set(source_atom)%r - &
1294 : image_translation
1295 : IF (SQRT(SUM(cross_displacement**2)) > cross_cutoff) CYCLE
1296 : CALL interpolate_gapw_atom_grid_fields( &
1297 : grid_atom, harmonics, cross_displacement, cross_cutoff, nspins, &
1298 : rho_h, rho_s, drho_h, drho_s, tau_h, tau_s, &
1299 : cross_density, cross_grad, cross_kin, cross_density_spatial, &
1300 : cross_grad_spatial, cross_kin_spatial, calculate_spatial=.FALSE.)
1301 : IF (lsd) THEN
1302 : IF (use_atom_composite_density) THEN
1303 : composite_cross_density(composite_row, 1:2) = &
1304 : composite_cross_density(composite_row, 1:2) + &
1305 : cross_density(1:2)
1306 : END IF
1307 : IF (use_atom_composite_gradient) THEN
1308 : composite_cross_grad(composite_row, :, 1:2) = &
1309 : composite_cross_grad(composite_row, :, 1:2) + &
1310 : cross_grad(:, 1:2)
1311 : END IF
1312 : IF (use_atom_composite_tau) THEN
1313 : composite_cross_kin(composite_row, 1:2) = &
1314 : composite_cross_kin(composite_row, 1:2) + cross_kin(1:2)
1315 : END IF
1316 : ELSE
1317 : IF (use_atom_composite_density) THEN
1318 : composite_cross_density(composite_row, :) = &
1319 : composite_cross_density(composite_row, :) + &
1320 : 0.5_dp*cross_density(1)
1321 : END IF
1322 : IF (use_atom_composite_gradient) THEN
1323 : DO idir = 1, 3
1324 : composite_cross_grad(composite_row, idir, :) = &
1325 : composite_cross_grad(composite_row, idir, :) + &
1326 : 0.5_dp*cross_grad(idir, 1)
1327 : END DO
1328 : END IF
1329 : IF (use_atom_composite_tau) THEN
1330 : composite_cross_kin(composite_row, :) = &
1331 : composite_cross_kin(composite_row, :) + &
1332 : 0.5_dp*cross_kin(1)
1333 : END IF
1334 : END IF
1335 : END DO
1336 : END DO
1337 : END DO
1338 : END DO
1339 : !$OMP END PARALLEL DO
1340 : END DO
1341 :
1342 452 : CALL release_tau_basis_cache(tau_basis_cache)
1343 : END DO
1344 : END IF
1345 :
1346 264 : IF (native_grid_diagnostics) THEN
1347 119570 : composite_cross_density_max = MAXVAL(ABS(composite_cross_density))
1348 358710 : composite_cross_grad_max = MAXVAL(ABS(composite_cross_grad))
1349 119570 : composite_cross_kin_max = MAXVAL(ABS(composite_cross_kin))
1350 30 : CALL para_env%max(composite_cross_cutoff_max)
1351 30 : CALL para_env%max(composite_cross_density_max)
1352 30 : CALL para_env%max(composite_cross_grad_max)
1353 30 : CALL para_env%max(composite_cross_kin_max)
1354 30 : iw = cp_logger_get_default_io_unit()
1355 30 : IF (iw > 0) THEN
1356 : WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES20.12))") &
1357 15 : "SKALA_GPW| Atom-composite cross support/maxima", &
1358 15 : composite_cross_cutoff_max, composite_cross_density_max, &
1359 30 : composite_cross_grad_max, composite_cross_kin_max
1360 : END IF
1361 : END IF
1362 917312 : composite_density(:, :) = composite_density(:, :) + composite_cross_density(:, :)
1363 2751936 : composite_grad(:, :, :) = composite_grad(:, :, :) + composite_cross_grad(:, :, :)
1364 917312 : composite_kin(:, :) = composite_kin(:, :) + composite_cross_kin(:, :)
1365 264 : DEALLOCATE (composite_cross_density, composite_cross_grad, composite_cross_kin)
1366 :
1367 458524 : CPASSERT(ALL(composite_grid_weights >= 0.0_dp))
1368 : atom_composite_nelec = SUM(composite_grid_weights* &
1369 458524 : (composite_density(:, 1) + composite_density(:, 2)))
1370 264 : CALL para_env%sum(atom_composite_nelec)
1371 264 : IF (atom_composite_reference .AND. my_calculate_forces) THEN
1372 : CALL skala_gapw_atom_composite_energy( &
1373 : my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
1374 : composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
1375 : composite_local_grid_sizes, composite_local_atom_coords, atom_composite_exc, &
1376 : composite_density_grad, composite_grad_grad, composite_kin_grad, &
1377 : composite_grid_coord_grad, composite_grid_weight_grad, &
1378 64 : composite_atomic_grid_weight_grad, composite_atom_coord_grad)
1379 0 : ALLOCATE (composite_cross_force(3, SIZE(particle_set)), &
1380 0 : composite_explicit_force(3, SIZE(particle_set)), &
1381 0 : composite_grid_coord_force(3, SIZE(particle_set)), &
1382 0 : composite_model_atom_force(3, SIZE(particle_set)), &
1383 0 : composite_moving_smooth_force(3, SIZE(particle_set)), &
1384 0 : composite_nlcc_center_force(3, SIZE(particle_set)), &
1385 0 : composite_nlcc_target_force(3, SIZE(particle_set)), &
1386 0 : composite_partition_force(3, SIZE(particle_set)), &
1387 0 : composite_partition_included(SIZE(particle_set)), &
1388 0 : composite_partition_datom(3, SIZE(particle_set), SIZE(particle_set)), &
1389 1088 : composite_partition_dstrain(3, 3, SIZE(particle_set)))
1390 64 : composite_cross_force = 0.0_dp
1391 64 : composite_cross_image_virial = 0.0_dp
1392 64 : composite_model_atom_force = 0.0_dp
1393 64 : composite_grid_coord_force = 0.0_dp
1394 64 : composite_moving_smooth_force = 0.0_dp
1395 64 : composite_nlcc_center_force = 0.0_dp
1396 64 : composite_nlcc_target_force = 0.0_dp
1397 64 : composite_partition_force = 0.0_dp
1398 64 : composite_explicit_virial = 0.0_dp
1399 64 : composite_feature_virial = 0.0_dp
1400 64 : composite_interpolation_virial = 0.0_dp
1401 64 : composite_partition_strain_virial = 0.0_dp
1402 : !$OMP PARALLEL DO IF (image_partition_atom_composite) SCHEDULE(STATIC) DEFAULT(NONE) &
1403 : !$OMP PRIVATE(composite_local_atom, composite_row, composite_smooth_gradient_value, &
1404 : !$OMP iatom, idir, ispin, jdir) &
1405 : !$OMP SHARED(cell, composite_atom_end, composite_atom_start, composite_grad_grad, &
1406 : !$OMP composite_grid_coords, composite_local_atoms, composite_local_natom, &
1407 : !$OMP composite_smooth_drho, composite_smooth_drhoa, composite_smooth_drhob, &
1408 : !$OMP image_partition_atom_composite, lsd, smooth_rho_r) &
1409 64 : !$OMP REDUCTION(+:composite_feature_virial)
1410 : DO composite_local_atom = 1, composite_local_natom
1411 : iatom = composite_local_atoms(composite_local_atom)
1412 : DO composite_row = composite_atom_start(iatom), composite_atom_end(iatom)
1413 : IF (lsd) THEN
1414 : DO jdir = 1, 3
1415 : composite_smooth_gradient_value(jdir, 1) = &
1416 : interpolate_native_grid( &
1417 : composite_smooth_drhoa(jdir)%array, smooth_rho_r(1)%pw_grid, &
1418 : cell, composite_grid_coords(:, composite_row), &
1419 : image_partition_atom_composite)
1420 : composite_smooth_gradient_value(jdir, 2) = &
1421 : interpolate_native_grid( &
1422 : composite_smooth_drhob(jdir)%array, smooth_rho_r(1)%pw_grid, &
1423 : cell, composite_grid_coords(:, composite_row), &
1424 : image_partition_atom_composite)
1425 : END DO
1426 : ELSE
1427 : DO jdir = 1, 3
1428 : composite_smooth_gradient_value(jdir, :) = 0.5_dp* &
1429 : interpolate_native_grid( &
1430 : composite_smooth_drho(jdir)%array, smooth_rho_r(1)%pw_grid, &
1431 : cell, composite_grid_coords(:, composite_row), &
1432 : image_partition_atom_composite)
1433 : END DO
1434 : END IF
1435 : DO ispin = 1, 2
1436 : DO idir = 1, 3
1437 : DO jdir = 1, 3
1438 : composite_feature_virial(jdir, idir) = &
1439 : composite_feature_virial(jdir, idir) - &
1440 : composite_grad_grad(composite_row, idir, ispin)* &
1441 : composite_smooth_gradient_value(jdir, ispin)
1442 : END DO
1443 : END DO
1444 : END DO
1445 : END DO
1446 : END DO
1447 : !$OMP END PARALLEL DO
1448 : !$OMP PARALLEL IF (image_partition_atom_composite) DEFAULT(NONE) &
1449 : !$OMP PRIVATE(composite_local_atom, composite_row, descriptor_window_adjoint, &
1450 : !$OMP descriptor_window_weight, gth_potential, iatom, idir, ispin, jdir, &
1451 : !$OMP nlcc_density, nlcc_gradient, nlcc_hessian, nlcc_spatial_derivative, &
1452 : !$OMP nlcc_spin_factor, partition_adjoint, composite_nlcc_center_force_local, &
1453 : !$OMP composite_partition_force_local, local_descriptor_datom, &
1454 : !$OMP local_descriptor_dstrain, local_partition_datom, local_partition_dstrain, &
1455 : !$OMP local_partition_weight, sgp_potential, source_atom, &
1456 : !$OMP spatial_derivative, target_atom, target_partition_adjoint) &
1457 : !$OMP REDUCTION(+:composite_interpolation_virial, composite_partition_strain_virial) &
1458 : !$OMP SHARED(cell, composite_atom_coord_grad, composite_atom_coords, composite_atom_end, &
1459 : !$OMP composite_atom_kind, composite_atom_start, composite_atomic_grid_weight_grad, &
1460 : !$OMP composite_atomic_grid_weights, composite_base_grid_weights, composite_density_grad, &
1461 : !$OMP composite_grad_grad, composite_grid_coord_force, composite_grid_coord_grad, &
1462 : !$OMP composite_grid_coords, composite_grid_weight_grad, composite_image_periodicity, &
1463 : !$OMP composite_kin_grad, composite_local_atoms, composite_local_natom, &
1464 : !$OMP composite_model_atom_force, composite_moving_smooth_force, &
1465 : !$OMP composite_nlcc_center_force, composite_nlcc_target_force, composite_partition_datom, &
1466 : !$OMP composite_partition_dstrain, composite_partition_force, composite_partition_included, &
1467 : !$OMP composite_partition_weights, composite_smooth_drho, composite_smooth_drhoa, &
1468 : !$OMP composite_smooth_drhob, composite_smooth_rho, composite_smooth_rhoa, &
1469 : !$OMP composite_smooth_rhob, composite_smooth_tau, composite_smooth_tau_a, &
1470 : !$OMP composite_smooth_tau_b, image_partition_atom_composite, lsd, my_kind_set, nlcc, &
1471 64 : !$OMP particle_set, smooth_rho_r)
1472 : ALLOCATE (composite_nlcc_center_force_local(3, SIZE(particle_set)), &
1473 : composite_partition_force_local(3, SIZE(particle_set)), &
1474 : local_partition_datom(3, SIZE(particle_set)))
1475 : composite_nlcc_center_force_local = 0.0_dp
1476 : composite_partition_force_local = 0.0_dp
1477 : !$OMP DO SCHEDULE(DYNAMIC)
1478 : DO composite_local_atom = 1, composite_local_natom
1479 : iatom = composite_local_atoms(composite_local_atom)
1480 : composite_model_atom_force(:, iatom) = &
1481 : composite_atom_coord_grad(:, composite_local_atom)
1482 : DO composite_row = composite_atom_start(iatom), composite_atom_end(iatom)
1483 : composite_grid_coord_force(:, iatom) = &
1484 : composite_grid_coord_force(:, iatom) + &
1485 : composite_grid_coord_grad(:, composite_row)
1486 : IF (lsd) THEN
1487 : spatial_derivative = &
1488 : composite_density_grad(composite_row, 1)* &
1489 : interpolate_native_grid_gradient( &
1490 : composite_smooth_rhoa, smooth_rho_r(1)%pw_grid, cell, &
1491 : composite_grid_coords(:, composite_row), &
1492 : image_partition_atom_composite) + &
1493 : composite_density_grad(composite_row, 2)* &
1494 : interpolate_native_grid_gradient( &
1495 : composite_smooth_rhob, smooth_rho_r(1)%pw_grid, cell, &
1496 : composite_grid_coords(:, composite_row), &
1497 : image_partition_atom_composite) + &
1498 : composite_kin_grad(composite_row, 1)* &
1499 : interpolate_native_grid_gradient( &
1500 : composite_smooth_tau_a, smooth_rho_r(1)%pw_grid, cell, &
1501 : composite_grid_coords(:, composite_row), &
1502 : image_partition_atom_composite) + &
1503 : composite_kin_grad(composite_row, 2)* &
1504 : interpolate_native_grid_gradient( &
1505 : composite_smooth_tau_b, smooth_rho_r(1)%pw_grid, cell, &
1506 : composite_grid_coords(:, composite_row), &
1507 : image_partition_atom_composite)
1508 : DO idir = 1, 3
1509 : spatial_derivative = spatial_derivative + &
1510 : composite_grad_grad(composite_row, idir, 1)* &
1511 : interpolate_native_grid_gradient( &
1512 : composite_smooth_drhoa(idir)%array, &
1513 : smooth_rho_r(1)%pw_grid, cell, &
1514 : composite_grid_coords(:, composite_row), &
1515 : image_partition_atom_composite) + &
1516 : composite_grad_grad(composite_row, idir, 2)* &
1517 : interpolate_native_grid_gradient( &
1518 : composite_smooth_drhob(idir)%array, &
1519 : smooth_rho_r(1)%pw_grid, cell, &
1520 : composite_grid_coords(:, composite_row), &
1521 : image_partition_atom_composite)
1522 : END DO
1523 : ELSE
1524 : spatial_derivative = 0.5_dp*SUM( &
1525 : composite_density_grad(composite_row, :))* &
1526 : interpolate_native_grid_gradient( &
1527 : composite_smooth_rho, smooth_rho_r(1)%pw_grid, cell, &
1528 : composite_grid_coords(:, composite_row), &
1529 : image_partition_atom_composite) + &
1530 : 0.5_dp*SUM(composite_kin_grad(composite_row, :))* &
1531 : interpolate_native_grid_gradient( &
1532 : composite_smooth_tau, smooth_rho_r(1)%pw_grid, cell, &
1533 : composite_grid_coords(:, composite_row), &
1534 : image_partition_atom_composite)
1535 : DO idir = 1, 3
1536 : spatial_derivative = spatial_derivative + 0.5_dp*SUM( &
1537 : composite_grad_grad(composite_row, idir, :))* &
1538 : interpolate_native_grid_gradient( &
1539 : composite_smooth_drho(idir)%array, &
1540 : smooth_rho_r(1)%pw_grid, &
1541 : cell, composite_grid_coords(:, composite_row), &
1542 : image_partition_atom_composite)
1543 : END DO
1544 : END IF
1545 : DO idir = 1, 3
1546 : DO jdir = 1, 3
1547 : composite_interpolation_virial(idir, jdir) = &
1548 : composite_interpolation_virial(idir, jdir) + &
1549 : spatial_derivative(idir)*( &
1550 : composite_grid_coords(jdir, composite_row) - &
1551 : particle_set(iatom)%r(jdir))
1552 : END DO
1553 : END DO
1554 : composite_moving_smooth_force(:, iatom) = &
1555 : composite_moving_smooth_force(:, iatom) + spatial_derivative
1556 : IF (nlcc) THEN
1557 : nlcc_spin_factor = MERGE(1.0_dp, 0.5_dp, lsd)
1558 : DO source_atom = 1, SIZE(particle_set)
1559 : NULLIFY (gth_potential, sgp_potential)
1560 : CALL get_qs_kind(my_kind_set(composite_atom_kind(source_atom)), &
1561 : gth_potential=gth_potential, &
1562 : sgp_potential=sgp_potential)
1563 : CALL evaluate_nlcc_primitive_fields( &
1564 : composite_grid_coords(:, composite_row), &
1565 : particle_set(source_atom)%r, gth_potential, sgp_potential, &
1566 : nlcc_density, nlcc_gradient, nlcc_hessian)
1567 : nlcc_spatial_derivative = 0.0_dp
1568 : DO ispin = 1, 2
1569 : nlcc_spatial_derivative = nlcc_spatial_derivative + &
1570 : nlcc_spin_factor*composite_density_grad(composite_row, ispin)* &
1571 : nlcc_gradient
1572 : DO idir = 1, 3
1573 : DO jdir = 1, 3
1574 : nlcc_spatial_derivative(jdir) = &
1575 : nlcc_spatial_derivative(jdir) + nlcc_spin_factor* &
1576 : composite_grad_grad(composite_row, idir, ispin)* &
1577 : nlcc_hessian(idir, jdir)
1578 : END DO
1579 : END DO
1580 : END DO
1581 : composite_nlcc_target_force(:, iatom) = &
1582 : composite_nlcc_target_force(:, iatom) + nlcc_spatial_derivative
1583 : composite_nlcc_center_force_local(:, source_atom) = &
1584 : composite_nlcc_center_force_local(:, source_atom) - nlcc_spatial_derivative
1585 : END DO
1586 : END IF
1587 : IF (image_partition_atom_composite) THEN
1588 : CALL periodic_atom_image_partition( &
1589 : composite_grid_coords(:, composite_row), composite_atom_coords, cell, &
1590 : iatom, local_partition_weight, local_partition_datom, &
1591 : local_partition_dstrain, composite_image_periodicity)
1592 : CALL periodic_atom_image_partition( &
1593 : composite_grid_coords(:, composite_row), &
1594 : composite_atom_coords(:, iatom:iatom), cell, 1, &
1595 : descriptor_window_weight, local_descriptor_datom, &
1596 : local_descriptor_dstrain, composite_image_periodicity)
1597 : ! Its atom derivative cancels against the moving target grid; periodic
1598 : ! image strain remains an explicit contribution to the virial.
1599 : target_partition_adjoint = composite_base_grid_weights(composite_row)* &
1600 : composite_grid_weight_grad(composite_row)
1601 : descriptor_window_adjoint = composite_base_grid_weights(composite_row)* &
1602 : composite_atomic_grid_weight_grad(composite_row)* &
1603 : smooth_partition_atomic_weight_scale_derivative( &
1604 : descriptor_window_weight)
1605 : DO target_atom = 1, SIZE(particle_set)
1606 : composite_partition_force_local(:, target_atom) = &
1607 : composite_partition_force_local(:, target_atom) + &
1608 : target_partition_adjoint*local_partition_datom(:, target_atom)
1609 : END DO
1610 : composite_partition_force_local(:, iatom) = &
1611 : composite_partition_force_local(:, iatom) - target_partition_adjoint* &
1612 : SUM(local_partition_datom, DIM=2)
1613 : composite_partition_strain_virial = &
1614 : composite_partition_strain_virial - target_partition_adjoint* &
1615 : local_partition_dstrain - descriptor_window_adjoint* &
1616 : local_descriptor_dstrain
1617 : ELSE
1618 : CALL skala_gpw_smooth_partition_derivatives( &
1619 : composite_grid_coords(:, composite_row), composite_atom_coords, cell, &
1620 : composite_partition_weights, composite_partition_included, &
1621 : composite_partition_datom, composite_partition_dstrain)
1622 : partition_adjoint = composite_grid_weight_grad(composite_row)* &
1623 : composite_atomic_grid_weights(composite_row)
1624 : DO target_atom = 1, SIZE(particle_set)
1625 : composite_partition_force_local(:, target_atom) = &
1626 : composite_partition_force_local(:, target_atom) + &
1627 : partition_adjoint* &
1628 : composite_partition_datom(:, target_atom, iatom)
1629 : END DO
1630 : composite_partition_force_local(:, iatom) = &
1631 : composite_partition_force_local(:, iatom) - partition_adjoint* &
1632 : SUM(composite_partition_datom(:, :, iatom), DIM=2)
1633 : END IF
1634 : END DO
1635 : END DO
1636 : !$OMP END DO
1637 : !$OMP CRITICAL(skala_atom_composite_force_reduction)
1638 : composite_nlcc_center_force(:, :) = composite_nlcc_center_force(:, :) + &
1639 : composite_nlcc_center_force_local
1640 : composite_partition_force(:, :) = composite_partition_force(:, :) + &
1641 : composite_partition_force_local
1642 : !$OMP END CRITICAL(skala_atom_composite_force_reduction)
1643 : DEALLOCATE (composite_nlcc_center_force_local, composite_partition_force_local, &
1644 64 : local_partition_datom)
1645 : !$OMP END PARALLEL
1646 : ! The target atom grids can overlap augmentation regions of other atoms
1647 : ! and periodic images. Differentiate the same discrete interpolation used
1648 : ! in the forward composite fields, including the explicit image strain.
1649 64 : IF (.NOT. direct_valence_atom_composite) THEN
1650 90 : DO ikind = 1, SIZE(atomic_kind_set)
1651 54 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
1652 54 : NULLIFY (gth_potential, sgp_potential)
1653 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
1654 : gth_potential=gth_potential, harmonics=harmonics, &
1655 : grid_atom=grid_atom, sgp_potential=sgp_potential, &
1656 54 : zatom=zatom, zeff=zeff)
1657 54 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
1658 66 : IF (.NOT. native_skala_uses_one_center_kind( &
1659 : paw_atom, gapw_representation, &
1660 : ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
1661 : zeff, zatom)) CYCLE
1662 :
1663 52 : nr = grid_atom%nr
1664 52 : na = grid_atom%ng_sphere
1665 52 : CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
1666 52 : CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
1667 52 : CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
1668 52 : CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
1669 52 : CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
1670 52 : CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
1671 52 : CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
1672 :
1673 122 : DO iat = 1, natom
1674 70 : source_atom = atom_list(iat)
1675 70 : rho_atom => my_rho_atom_set(source_atom)
1676 70 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
1677 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s, &
1678 : drho_rad_h=dr_h, drho_rad_s=dr_s, &
1679 70 : rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
1680 102140 : rho_h = 0.0_dp
1681 102140 : rho_s = 0.0_dp
1682 500220 : drho_h = 0.0_dp
1683 500220 : drho_s = 0.0_dp
1684 70 : CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
1685 2550 : DO ir = 1, nr
1686 : CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
1687 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
1688 2550 : r_h_d, r_s_d, drho_h, drho_s)
1689 : END DO
1690 :
1691 : cross_cutoff = gapw_atom_grid_support_radius( &
1692 70 : grid_atom, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s)
1693 70 : IF (cross_cutoff <= 0.0_dp) CYCLE
1694 58 : image_shell = 0
1695 232 : DO idir = 1, 3
1696 232 : IF (cell%perd(idir) == 1) THEN
1697 : image_shell(idir) = CEILING( &
1698 600 : cross_cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))) + 1
1699 : END IF
1700 : END DO
1701 :
1702 : !$OMP PARALLEL DEFAULT(NONE) &
1703 : !$OMP PRIVATE(image_lower, image_upper, composite_cross_force_local, composite_cross_image_virial_local, &
1704 : !$OMP composite_row, cross_density, cross_density_adjoint, cross_density_spatial, &
1705 : !$OMP cross_displacement, cross_grad, cross_grad_adjoint, cross_grad_spatial, &
1706 : !$OMP cross_kin, cross_kin_adjoint, cross_kin_spatial, cross_spatial_derivative, &
1707 : !$OMP fractional, idir, image_i1, image_i2, image_i3, image_shift, image_translation, &
1708 : !$OMP ispin, jdir, target_atom) &
1709 : !$OMP SHARED(cell, composite_cross_force, composite_cross_image_virial, &
1710 : !$OMP composite_density_grad, composite_grad_grad, composite_grid_atom, &
1711 : !$OMP composite_grid_coords, composite_kin_grad, composite_nflat, cross_cutoff, &
1712 : !$OMP drho_h, drho_s, grid_atom, harmonics, image_shell, lsd, nspins, &
1713 : !$OMP particle_set, rho_h, rho_s, source_atom, tau_h, tau_s, &
1714 122 : !$OMP use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau)
1715 : ALLOCATE (composite_cross_force_local(3, SIZE(particle_set)))
1716 : composite_cross_force_local = 0.0_dp
1717 : composite_cross_image_virial_local = 0.0_dp
1718 : !$OMP DO SCHEDULE(STATIC)
1719 : DO composite_row = 1, composite_nflat
1720 : target_atom = composite_grid_atom(composite_row)
1721 : IF (lsd) THEN
1722 : cross_density_adjoint = 0.0_dp
1723 : cross_grad_adjoint = 0.0_dp
1724 : cross_kin_adjoint = 0.0_dp
1725 : IF (use_atom_composite_density) THEN
1726 : cross_density_adjoint(1:2) = &
1727 : composite_density_grad(composite_row, 1:2)
1728 : END IF
1729 : IF (use_atom_composite_gradient) THEN
1730 : cross_grad_adjoint(:, 1:2) = &
1731 : composite_grad_grad(composite_row, :, 1:2)
1732 : END IF
1733 : IF (use_atom_composite_tau) THEN
1734 : cross_kin_adjoint(1:2) = &
1735 : composite_kin_grad(composite_row, 1:2)
1736 : END IF
1737 : ELSE
1738 : cross_density_adjoint = 0.0_dp
1739 : cross_grad_adjoint = 0.0_dp
1740 : cross_kin_adjoint = 0.0_dp
1741 : IF (use_atom_composite_density) THEN
1742 : cross_density_adjoint(1) = 0.5_dp* &
1743 : SUM(composite_density_grad(composite_row, :))
1744 : END IF
1745 : IF (use_atom_composite_gradient) THEN
1746 : DO idir = 1, 3
1747 : cross_grad_adjoint(idir, 1) = 0.5_dp* &
1748 : SUM(composite_grad_grad(composite_row, idir, :))
1749 : END DO
1750 : END IF
1751 : IF (use_atom_composite_tau) THEN
1752 : cross_kin_adjoint(1) = 0.5_dp* &
1753 : SUM(composite_kin_grad(composite_row, :))
1754 : END IF
1755 : END IF
1756 :
1757 : fractional = 0.0_dp
1758 : DO idir = 1, 3
1759 : DO jdir = 1, 3
1760 : fractional(idir) = fractional(idir) + cell%h_inv(idir, jdir)* &
1761 : (composite_grid_coords(jdir, composite_row) - &
1762 : particle_set(source_atom)%r(jdir))
1763 : END DO
1764 : END DO
1765 : CALL atom_grid_image_bounds(cell, fractional, cross_cutoff, image_shell, &
1766 : image_lower, image_upper)
1767 : DO image_i3 = image_lower(3), image_upper(3)
1768 : DO image_i2 = image_lower(2), image_upper(2)
1769 : DO image_i1 = image_lower(1), image_upper(1)
1770 : image_shift = [image_i1, image_i2, image_i3]
1771 : IF (target_atom == source_atom .AND. &
1772 : ALL(image_shift == 0)) CYCLE
1773 : image_translation = MATMUL( &
1774 : cell%hmat, REAL(image_shift, dp))
1775 : cross_displacement = &
1776 : composite_grid_coords(:, composite_row) - &
1777 : particle_set(source_atom)%r - image_translation
1778 : IF (SQRT(SUM(cross_displacement**2)) > cross_cutoff) CYCLE
1779 : CALL interpolate_gapw_atom_grid_fields( &
1780 : grid_atom, harmonics, cross_displacement, cross_cutoff, &
1781 : nspins, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s, &
1782 : cross_density, cross_grad, cross_kin, cross_density_spatial, &
1783 : cross_grad_spatial, cross_kin_spatial)
1784 : cross_spatial_derivative = 0.0_dp
1785 : DO ispin = 1, nspins
1786 : DO idir = 1, 3
1787 : cross_spatial_derivative(idir) = &
1788 : cross_spatial_derivative(idir) + &
1789 : cross_density_adjoint(ispin)* &
1790 : cross_density_spatial(idir, ispin) + &
1791 : cross_kin_adjoint(ispin)* &
1792 : cross_kin_spatial(idir, ispin)
1793 : DO jdir = 1, 3
1794 : cross_spatial_derivative(idir) = &
1795 : cross_spatial_derivative(idir) + &
1796 : cross_grad_adjoint(jdir, ispin)* &
1797 : cross_grad_spatial(jdir, idir, ispin)
1798 : END DO
1799 : END DO
1800 : END DO
1801 : composite_cross_force_local(:, target_atom) = &
1802 : composite_cross_force_local(:, target_atom) + &
1803 : cross_spatial_derivative
1804 : composite_cross_force_local(:, source_atom) = &
1805 : composite_cross_force_local(:, source_atom) - &
1806 : cross_spatial_derivative
1807 : DO idir = 1, 3
1808 : DO jdir = 1, 3
1809 : composite_cross_image_virial_local(idir, jdir) = &
1810 : composite_cross_image_virial_local(idir, jdir) + &
1811 : cross_spatial_derivative(idir)*image_translation(jdir)
1812 : END DO
1813 : END DO
1814 : END DO
1815 : END DO
1816 : END DO
1817 : END DO
1818 : !$OMP END DO
1819 : !$OMP CRITICAL(skala_atom_composite_cross_reduction)
1820 : composite_cross_force(:, :) = &
1821 : composite_cross_force(:, :) + composite_cross_force_local(:, :)
1822 : composite_cross_image_virial = composite_cross_image_virial + &
1823 : composite_cross_image_virial_local
1824 : !$OMP END CRITICAL(skala_atom_composite_cross_reduction)
1825 : DEALLOCATE (composite_cross_force_local)
1826 : !$OMP END PARALLEL
1827 : END DO
1828 142 : CALL release_tau_basis_cache(tau_basis_cache)
1829 : END DO
1830 : END IF
1831 :
1832 : composite_explicit_force(:, :) = composite_model_atom_force(:, :) + &
1833 : composite_grid_coord_force(:, :) + &
1834 : composite_moving_smooth_force(:, :) + &
1835 : composite_cross_force(:, :) + &
1836 : composite_nlcc_center_force(:, :) + &
1837 : composite_nlcc_target_force(:, :) + &
1838 576 : composite_partition_force(:, :)
1839 : ! CP2K stores +dE/dR in the electronic force components, while the
1840 : ! virial is -dE/dstrain. Model coordinates, atom-grid centers,
1841 : ! NLCC centers, and partition centers move affinely with their atoms.
1842 : ! The smooth-field interpolation force is excluded here: its affine
1843 : ! response is already in the PW stress and its non-affine local-grid
1844 : ! correction is composite_interpolation_virial.
1845 192 : DO iatom = 1, SIZE(particle_set)
1846 576 : DO idir = 1, 3
1847 1664 : DO jdir = 1, 3
1848 : composite_explicit_virial(idir, jdir) = &
1849 : composite_explicit_virial(idir, jdir) - ( &
1850 : composite_model_atom_force(idir, iatom) + &
1851 : composite_grid_coord_force(idir, iatom) + &
1852 : composite_cross_force(idir, iatom) + &
1853 : composite_nlcc_center_force(idir, iatom) + &
1854 : composite_nlcc_target_force(idir, iatom) + &
1855 1536 : composite_partition_force(idir, iatom))*particle_set(iatom)%r(jdir)
1856 : END DO
1857 : END DO
1858 : END DO
1859 : composite_explicit_virial = composite_explicit_virial + &
1860 : composite_partition_strain_virial + &
1861 832 : composite_cross_image_virial
1862 64 : IF (ASSOCIATED(force)) THEN
1863 192 : DO iatom = 1, SIZE(particle_set)
1864 128 : ikind = composite_atom_kind(iatom)
1865 128 : iat = composite_atom_kind_index(iatom)
1866 128 : CPASSERT(ikind > 0 .AND. iat > 0)
1867 : force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
1868 576 : composite_explicit_force(:, iatom)
1869 : END DO
1870 : END IF
1871 64 : IF (use_virial) THEN
1872 : ! The local radial vectors of the atom-centered quadrature do not
1873 : ! deform with the periodic cell. Correct the standard PW response,
1874 : ! which follows fixed fractional coordinates, by the corresponding
1875 : ! non-affine interpolation derivative.
1876 702 : virial%pv_xc = composite_feature_virial - composite_interpolation_virial
1877 702 : virial%pv_gapw = virial%pv_gapw + composite_explicit_virial
1878 702 : virial%pv_virial = virial%pv_virial + composite_explicit_virial
1879 : END IF
1880 64 : IF (native_grid_diagnostics) THEN
1881 14 : CALL para_env%sum(composite_cross_force)
1882 14 : CALL para_env%sum(composite_cross_image_virial)
1883 14 : CALL para_env%sum(composite_model_atom_force)
1884 14 : CALL para_env%sum(composite_grid_coord_force)
1885 14 : CALL para_env%sum(composite_moving_smooth_force)
1886 14 : CALL para_env%sum(composite_nlcc_center_force)
1887 14 : CALL para_env%sum(composite_nlcc_target_force)
1888 14 : CALL para_env%sum(composite_partition_force)
1889 14 : CALL para_env%sum(composite_explicit_force)
1890 14 : CALL para_env%sum(composite_explicit_virial)
1891 14 : CALL para_env%sum(composite_feature_virial)
1892 14 : CALL para_env%sum(composite_interpolation_virial)
1893 14 : iw = cp_logger_get_default_io_unit()
1894 14 : IF (iw > 0) THEN
1895 21 : DO iatom = 1, SIZE(particle_set)
1896 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1897 14 : "SKALA_GPW| Atom-composite model-atom force", iatom, &
1898 28 : composite_model_atom_force(:, iatom)
1899 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1900 14 : "SKALA_GPW| Atom-composite grid-coordinate force", iatom, &
1901 28 : composite_grid_coord_force(:, iatom)
1902 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1903 14 : "SKALA_GPW| Atom-composite moving-smooth force", iatom, &
1904 28 : composite_moving_smooth_force(:, iatom)
1905 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1906 14 : "SKALA_GPW| Atom-composite cross-region force", iatom, &
1907 28 : composite_cross_force(:, iatom)
1908 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1909 14 : "SKALA_GPW| Atom-composite NLCC-center force", iatom, &
1910 28 : composite_nlcc_center_force(:, iatom)
1911 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1912 14 : "SKALA_GPW| Atom-composite NLCC-target force", iatom, &
1913 28 : composite_nlcc_target_force(:, iatom)
1914 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1915 14 : "SKALA_GPW| Atom-composite partition force", iatom, &
1916 28 : composite_partition_force(:, iatom)
1917 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES20.12))") &
1918 14 : "SKALA_GPW| Atom-composite explicit force", iatom, &
1919 35 : composite_explicit_force(:, iatom)
1920 : END DO
1921 : WRITE (UNIT=iw, FMT="(T2,A)") &
1922 7 : "SKALA_GPW| Atom-composite explicit virial"
1923 28 : DO idir = 1, 3
1924 : WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
1925 28 : "SKALA_GPW|", composite_explicit_virial(idir, :)
1926 : END DO
1927 : WRITE (UNIT=iw, FMT="(T2,A)") &
1928 7 : "SKALA_GPW| Atom-composite cross-image virial"
1929 28 : DO idir = 1, 3
1930 : WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
1931 28 : "SKALA_GPW|", composite_cross_image_virial(idir, :)
1932 : END DO
1933 : WRITE (UNIT=iw, FMT="(T2,A)") &
1934 7 : "SKALA_GPW| Atom-composite feature virial"
1935 28 : DO idir = 1, 3
1936 : WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
1937 28 : "SKALA_GPW|", composite_feature_virial(idir, :)
1938 : END DO
1939 : WRITE (UNIT=iw, FMT="(T2,A)") &
1940 7 : "SKALA_GPW| Atom-composite interpolation virial"
1941 28 : DO idir = 1, 3
1942 : WRITE (UNIT=iw, FMT="(T2,A,1X,3ES20.10)") &
1943 28 : "SKALA_GPW|", composite_interpolation_virial(idir, :)
1944 : END DO
1945 : END IF
1946 : END IF
1947 0 : DEALLOCATE (composite_atom_coord_grad, composite_atomic_grid_weight_grad, &
1948 0 : composite_cross_force, &
1949 0 : composite_explicit_force, composite_grid_coord_force, &
1950 0 : composite_grid_coord_grad, composite_grid_weight_grad, &
1951 0 : composite_model_atom_force, composite_moving_smooth_force, &
1952 0 : composite_nlcc_center_force, &
1953 0 : composite_nlcc_target_force, &
1954 0 : composite_partition_datom, composite_partition_dstrain, &
1955 64 : composite_partition_force, composite_partition_included)
1956 : ELSE
1957 : CALL skala_gapw_atom_composite_energy( &
1958 : my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
1959 : composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
1960 : composite_local_grid_sizes, composite_local_atom_coords, atom_composite_exc, &
1961 200 : composite_density_grad, composite_grad_grad, composite_kin_grad)
1962 : END IF
1963 1056 : composite_pw_nflat = PRODUCT(smooth_rho_r(1)%pw_grid%npts)
1964 264 : adjoint_nchannels = MERGE(2, 1, lsd)
1965 0 : ALLOCATE (smooth_density_adjoint_storage(composite_pw_nflat, adjoint_nchannels), &
1966 0 : smooth_grad_adjoint_storage(composite_pw_nflat, 3, adjoint_nchannels), &
1967 2376 : smooth_kin_adjoint_storage(composite_pw_nflat, adjoint_nchannels))
1968 264 : smooth_density_adjoint_storage = 0.0_dp
1969 264 : smooth_grad_adjoint_storage = 0.0_dp
1970 264 : smooth_kin_adjoint_storage = 0.0_dp
1971 : CALL build_native_grid_adjoint_bins( &
1972 : smooth_rho_r(1)%pw_grid, cell, composite_grid_coords, &
1973 : image_partition_atom_composite, adjoint_tile_count, adjoint_bin_offsets, &
1974 264 : adjoint_bin_rows)
1975 264 : adjoint_nbins = SIZE(adjoint_bin_offsets) - 1
1976 : !$OMP PARALLEL DO SCHEDULE(DYNAMIC) DEFAULT(NONE) &
1977 : !$OMP PRIVATE(adjoint_entry, composite_row, composite_smooth_density_adjoint_value, &
1978 : !$OMP composite_smooth_gradient_adjoint_value, composite_smooth_kin_adjoint_value, &
1979 : !$OMP adjoint_tile_lower, adjoint_tile_upper, interpolation_stencil) &
1980 : !$OMP SHARED(adjoint_bin_offsets, adjoint_bin_rows, adjoint_nbins, adjoint_nchannels, &
1981 : !$OMP adjoint_tile_count, cell, composite_density_grad, composite_grad_grad, &
1982 : !$OMP composite_grid_coords, composite_kin_grad, image_partition_atom_composite, lsd, &
1983 : !$OMP smooth_density_adjoint_storage, smooth_grad_adjoint_storage, &
1984 264 : !$OMP smooth_kin_adjoint_storage, smooth_rho_r, qs_env)
1985 : DO adjoint_bin = 1, adjoint_nbins
1986 : CALL native_grid_adjoint_tile_bounds( &
1987 : smooth_rho_r(1)%pw_grid, adjoint_bin, adjoint_tile_count, &
1988 : adjoint_tile_lower, adjoint_tile_upper)
1989 : DO adjoint_entry = adjoint_bin_offsets(adjoint_bin), &
1990 : adjoint_bin_offsets(adjoint_bin + 1) - 1
1991 : composite_row = adjoint_bin_rows(adjoint_entry)
1992 : IF (.NOT. fetch_native_grid_stencil(qs_env%native_grid_cache, composite_row, &
1993 : composite_grid_coords(:, composite_row), interpolation_stencil)) THEN
1994 : CALL create_native_grid_interpolation_stencil( &
1995 : interpolation_stencil, smooth_rho_r(1)%pw_grid, cell, &
1996 : composite_grid_coords(:, composite_row), image_partition_atom_composite)
1997 : END IF
1998 : IF (lsd) THEN
1999 : composite_smooth_density_adjoint_value = &
2000 : composite_density_grad(composite_row, :)
2001 : composite_smooth_gradient_adjoint_value = &
2002 : composite_grad_grad(composite_row, :, :)
2003 : composite_smooth_kin_adjoint_value = composite_kin_grad(composite_row, :)
2004 : ELSE
2005 : composite_smooth_density_adjoint_value = 0.0_dp
2006 : composite_smooth_gradient_adjoint_value = 0.0_dp
2007 : composite_smooth_kin_adjoint_value = 0.0_dp
2008 : composite_smooth_density_adjoint_value(1) = &
2009 : SUM(composite_density_grad(composite_row, :))
2010 : composite_smooth_gradient_adjoint_value(:, 1) = &
2011 : SUM(composite_grad_grad(composite_row, :, :), DIM=2)
2012 : composite_smooth_kin_adjoint_value(1) = &
2013 : SUM(composite_kin_grad(composite_row, :))
2014 : END IF
2015 : CALL add_native_grid_fields_adjoint_tile( &
2016 : smooth_density_adjoint_storage, smooth_grad_adjoint_storage, &
2017 : smooth_kin_adjoint_storage, smooth_rho_r(1)%pw_grid, interpolation_stencil, &
2018 : composite_smooth_density_adjoint_value, &
2019 : composite_smooth_gradient_adjoint_value, &
2020 : composite_smooth_kin_adjoint_value, adjoint_nchannels, &
2021 : adjoint_tile_lower, adjoint_tile_upper)
2022 : END DO
2023 : END DO
2024 : !$OMP END PARALLEL DO
2025 264 : DEALLOCATE (adjoint_bin_offsets, adjoint_bin_rows)
2026 : smooth_input_contraction = 0.0_dp
2027 : !$OMP PARALLEL DO SCHEDULE(STATIC) REDUCTION(+:smooth_input_contraction) DEFAULT(NONE) &
2028 : !$OMP PRIVATE(composite_smooth_density_value, composite_smooth_gradient_value, &
2029 : !$OMP composite_smooth_kin_value, idir, ispin) &
2030 : !$OMP SHARED(composite_density_grad, composite_grad_grad, composite_kin_grad, composite_nflat, &
2031 : !$OMP composite_smooth_density_cache, composite_smooth_gradient_cache, &
2032 264 : !$OMP composite_smooth_kin_cache, lsd)
2033 : DO composite_row = 1, composite_nflat
2034 : composite_smooth_density_value = composite_smooth_density_cache(composite_row, :)
2035 : composite_smooth_gradient_value = &
2036 : composite_smooth_gradient_cache(composite_row, :, :)
2037 : composite_smooth_kin_value = composite_smooth_kin_cache(composite_row, :)
2038 : DO ispin = 1, 2
2039 : IF (lsd) THEN
2040 : smooth_input_contraction = smooth_input_contraction + &
2041 : composite_density_grad(composite_row, ispin)* &
2042 : composite_smooth_density_value(ispin) + &
2043 : composite_kin_grad(composite_row, ispin)* &
2044 : composite_smooth_kin_value(ispin)
2045 : DO idir = 1, 3
2046 : smooth_input_contraction = smooth_input_contraction + &
2047 : composite_grad_grad(composite_row, idir, ispin)* &
2048 : composite_smooth_gradient_value(idir, ispin)
2049 : END DO
2050 : ELSE
2051 : smooth_input_contraction = smooth_input_contraction + 0.5_dp*( &
2052 : composite_density_grad(composite_row, ispin)* &
2053 : composite_smooth_density_value(1) + &
2054 : composite_kin_grad(composite_row, ispin)* &
2055 : composite_smooth_kin_value(1))
2056 : DO idir = 1, 3
2057 : smooth_input_contraction = smooth_input_contraction + 0.5_dp* &
2058 : composite_grad_grad(composite_row, idir, ispin)* &
2059 : composite_smooth_gradient_value(idir, 1)
2060 : END DO
2061 : END IF
2062 : END DO
2063 : END DO
2064 : !$OMP END PARALLEL DO
2065 264 : smooth_density_adjoint => smooth_density_adjoint_storage
2066 264 : smooth_grad_adjoint => smooth_grad_adjoint_storage
2067 264 : smooth_kin_adjoint => smooth_kin_adjoint_storage
2068 : ! The interpolation transpose still uses CP2K's global FFT-grid layout. Reduce only
2069 : ! this PW adjoint; atom-grid feature rows and their model derivatives stay rank-local.
2070 4735008 : CALL para_env%sum(smooth_density_adjoint)
2071 14205108 : CALL para_env%sum(smooth_grad_adjoint)
2072 4735008 : CALL para_env%sum(smooth_kin_adjoint)
2073 264 : CALL para_env%sum(smooth_input_contraction)
2074 : CALL build_vxc_from_feature_grads( &
2075 : smooth_vxc_rho, smooth_vxc_tau, smooth_rho_r, auxbas_pw_pool, &
2076 : smooth_density_adjoint, smooth_grad_adjoint, smooth_kin_adjoint, &
2077 264 : xc_deriv_method_id, global_grid_layout=.TRUE.)
2078 264 : NULLIFY (smooth_density_adjoint, smooth_grad_adjoint, smooth_kin_adjoint)
2079 0 : DEALLOCATE (smooth_density_adjoint_storage, smooth_grad_adjoint_storage, &
2080 264 : smooth_kin_adjoint_storage)
2081 264 : smooth_grid_contraction = 0.0_dp
2082 570 : DO ispin = 1, nspins
2083 : smooth_grid_contraction = smooth_grid_contraction + smooth_rho_r(1)%pw_grid%dvol* &
2084 : (SUM(smooth_vxc_rho(ispin)%array* &
2085 : smooth_rho_r(ispin)%array) + &
2086 : SUM(smooth_vxc_tau(ispin)%array* &
2087 2597028 : smooth_tau_r(ispin)%array))
2088 306 : IF (atom_composite_reference) THEN
2089 306 : CPASSERT(PRESENT(composite_vxc_rho))
2090 306 : CPASSERT(PRESENT(composite_vxc_tau))
2091 306 : CPASSERT(ASSOCIATED(composite_vxc_rho))
2092 306 : CPASSERT(ASSOCIATED(composite_vxc_tau))
2093 306 : CPASSERT(SIZE(composite_vxc_rho) == nspins)
2094 306 : CPASSERT(SIZE(composite_vxc_tau) == nspins)
2095 306 : CALL pw_axpy(smooth_vxc_rho(ispin), composite_vxc_rho(ispin), 1.0_dp)
2096 306 : CALL pw_axpy(smooth_vxc_tau(ispin), composite_vxc_tau(ispin), 1.0_dp)
2097 : END IF
2098 306 : CALL auxbas_pw_pool%give_back_pw(smooth_vxc_rho(ispin))
2099 570 : CALL auxbas_pw_pool%give_back_pw(smooth_vxc_tau(ispin))
2100 : END DO
2101 264 : CALL para_env%sum(smooth_grid_contraction)
2102 264 : DEALLOCATE (smooth_vxc_rho, smooth_vxc_tau)
2103 :
2104 264 : one_center_field_contraction = 0.0_dp
2105 264 : one_center_matrix_contraction = 0.0_dp
2106 264 : one_center_density_field_contraction = 0.0_dp
2107 264 : one_center_density_matrix_contraction = 0.0_dp
2108 264 : one_center_gradient_field_contraction = 0.0_dp
2109 264 : one_center_gradient_matrix_contraction = 0.0_dp
2110 264 : one_center_rho_grad_field_contraction = 0.0_dp
2111 264 : one_center_rho_grad_matrix_contraction = 0.0_dp
2112 264 : one_center_tau_field_contraction = 0.0_dp
2113 264 : one_center_tau_matrix_contraction = 0.0_dp
2114 264 : IF (.NOT. direct_valence_atom_composite) THEN
2115 292 : DO ikind = 1, SIZE(atomic_kind_set)
2116 164 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
2117 164 : NULLIFY (gth_potential, sgp_potential)
2118 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
2119 : gth_potential=gth_potential, harmonics=harmonics, &
2120 : grid_atom=grid_atom, sgp_potential=sgp_potential, &
2121 164 : zatom=zatom, zeff=zeff)
2122 164 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
2123 188 : IF (.NOT. native_skala_uses_one_center_kind( &
2124 : paw_atom, gapw_representation, &
2125 : ASSOCIATED(gth_potential) .OR. ASSOCIATED(sgp_potential), &
2126 : zeff, zatom)) CYCLE
2127 :
2128 160 : nr = grid_atom%nr
2129 160 : na = grid_atom%ng_sphere
2130 160 : CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
2131 160 : CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
2132 160 : CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
2133 160 : CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
2134 160 : CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
2135 160 : CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
2136 160 : CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
2137 160 : CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
2138 160 : CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
2139 160 : CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
2140 160 : CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
2141 160 : CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
2142 160 : CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
2143 :
2144 160 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
2145 412 : DO iat = 1, natom
2146 252 : iatom = atom_list(iat)
2147 252 : source_matrix_local = iat >= bo(1) .AND. iat <= bo(2)
2148 252 : rho_atom => my_rho_atom_set(iatom)
2149 252 : NULLIFY (cpc_h, cpc_s, r_h, r_s, dr_h, dr_s, r_h_d, r_s_d, int_hh, int_ss)
2150 : CALL get_rho_atom(rho_atom=rho_atom, cpc_h=cpc_h, cpc_s=cpc_s, &
2151 : rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
2152 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d, &
2153 252 : ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
2154 238104 : rho_h = 0.0_dp
2155 238104 : rho_s = 0.0_dp
2156 1159704 : drho_h = 0.0_dp
2157 1159704 : drho_s = 0.0_dp
2158 252 : CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
2159 7452 : DO ir = 1, nr
2160 : CALL calc_rho_angular(grid_atom, harmonics, nspins, .TRUE., &
2161 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
2162 7452 : r_h_d, r_s_d, drho_h, drho_s)
2163 : END DO
2164 :
2165 238104 : vxc_h = 0.0_dp
2166 238104 : vxc_s = 0.0_dp
2167 929304 : vxg_h = 0.0_dp
2168 929304 : vxg_s = 0.0_dp
2169 238104 : vtau_h = 0.0_dp
2170 238104 : vtau_s = 0.0_dp
2171 252 : IF (source_matrix_local) THEN
2172 126 : composite_row = composite_atom_start(iatom) - 1
2173 3726 : DO ir = 1, nr
2174 118926 : DO ia = 1, na
2175 115200 : composite_row = composite_row + 1
2176 118800 : IF (lsd) THEN
2177 0 : IF (use_atom_composite_density) THEN
2178 0 : vxc_h(ia, ir, 1:2) = composite_density_grad(composite_row, 1:2)
2179 0 : vxc_s(ia, ir, 1:2) = composite_density_grad(composite_row, 1:2)
2180 : END IF
2181 0 : IF (use_atom_composite_gradient) THEN
2182 0 : DO idir = 1, 3
2183 : vxg_h(idir, ia, ir, 1:2) = &
2184 0 : composite_grad_grad(composite_row, idir, 1:2)
2185 : vxg_s(idir, ia, ir, 1:2) = &
2186 0 : composite_grad_grad(composite_row, idir, 1:2)
2187 : END DO
2188 : END IF
2189 0 : IF (use_atom_composite_tau) THEN
2190 0 : vtau_h(ia, ir, 1:2) = composite_kin_grad(composite_row, 1:2)
2191 0 : vtau_s(ia, ir, 1:2) = composite_kin_grad(composite_row, 1:2)
2192 : END IF
2193 : ELSE
2194 115200 : IF (use_atom_composite_density) THEN
2195 : vxc_h(ia, ir, 1) = 0.5_dp* &
2196 345600 : SUM(composite_density_grad(composite_row, :))
2197 115200 : vxc_s(ia, ir, 1) = vxc_h(ia, ir, 1)
2198 : END IF
2199 115200 : IF (use_atom_composite_gradient) THEN
2200 460800 : DO idir = 1, 3
2201 : vxg_h(idir, ia, ir, 1) = 0.5_dp* &
2202 : SUM(composite_grad_grad( &
2203 1036800 : composite_row, idir, :))
2204 460800 : vxg_s(idir, ia, ir, 1) = vxg_h(idir, ia, ir, 1)
2205 : END DO
2206 : END IF
2207 115200 : IF (use_atom_composite_tau) THEN
2208 : vtau_h(ia, ir, 1) = 0.5_dp* &
2209 345600 : SUM(composite_kin_grad(composite_row, :))
2210 115200 : vtau_s(ia, ir, 1) = vtau_h(ia, ir, 1)
2211 : END IF
2212 : END IF
2213 : END DO
2214 : END DO
2215 126 : CPASSERT(composite_row == composite_atom_end(iatom))
2216 : END IF
2217 :
2218 : cross_cutoff = gapw_atom_grid_support_radius( &
2219 252 : grid_atom, rho_h, rho_s, drho_h, drho_s, tau_h, tau_s)
2220 252 : IF (cross_cutoff > 0.0_dp) THEN
2221 228 : image_shell = 0
2222 912 : DO idir = 1, 3
2223 912 : IF (cell%perd(idir) == 1) THEN
2224 : image_shell(idir) = CEILING( &
2225 2544 : cross_cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))) + 1
2226 : END IF
2227 : END DO
2228 : ! Each thread accumulates its own one-center potentials; combine them
2229 : ! before the existing MPI reduction over target-atom owners.
2230 : !$OMP PARALLEL DEFAULT(NONE) &
2231 : !$OMP PRIVATE(image_lower, image_upper, composite_row, cross_density_adjoint, cross_displacement, &
2232 : !$OMP cross_grad_adjoint, cross_kin_adjoint, fractional, idir, image_i1, &
2233 : !$OMP image_i2, image_i3, image_shift, image_translation, jdir, target_atom, &
2234 : !$OMP vxc_h_local, vxc_s_local, vxg_h_local, vxg_s_local, vtau_h_local, vtau_s_local) &
2235 : !$OMP SHARED(cell, composite_density_grad, composite_grad_grad, composite_grid_atom, &
2236 : !$OMP composite_grid_coords, composite_kin_grad, composite_nflat, cross_cutoff, &
2237 : !$OMP grid_atom, harmonics, iatom, image_shell, lsd, nspins, particle_set, &
2238 : !$OMP use_atom_composite_density, use_atom_composite_gradient, use_atom_composite_tau, &
2239 228 : !$OMP vxc_h, vxc_s, vxg_h, vxg_s, vtau_h, vtau_s)
2240 : ALLOCATE (vxc_h_local, MOLD=vxc_h)
2241 : ALLOCATE (vxc_s_local, MOLD=vxc_s)
2242 : ALLOCATE (vxg_h_local, MOLD=vxg_h)
2243 : ALLOCATE (vxg_s_local, MOLD=vxg_s)
2244 : ALLOCATE (vtau_h_local, MOLD=vtau_h)
2245 : ALLOCATE (vtau_s_local, MOLD=vtau_s)
2246 : vxc_h_local = 0.0_dp
2247 : vxc_s_local = 0.0_dp
2248 : vxg_h_local = 0.0_dp
2249 : vxg_s_local = 0.0_dp
2250 : vtau_h_local = 0.0_dp
2251 : vtau_s_local = 0.0_dp
2252 : !$OMP DO SCHEDULE(STATIC)
2253 : DO composite_row = 1, composite_nflat
2254 : target_atom = composite_grid_atom(composite_row)
2255 : cross_density_adjoint = 0.0_dp
2256 : cross_grad_adjoint = 0.0_dp
2257 : cross_kin_adjoint = 0.0_dp
2258 : IF (lsd) THEN
2259 : IF (use_atom_composite_density) THEN
2260 : cross_density_adjoint(1:2) = &
2261 : composite_density_grad(composite_row, 1:2)
2262 : END IF
2263 : IF (use_atom_composite_gradient) THEN
2264 : cross_grad_adjoint(:, 1:2) = &
2265 : composite_grad_grad(composite_row, :, 1:2)
2266 : END IF
2267 : IF (use_atom_composite_tau) THEN
2268 : cross_kin_adjoint(1:2) = &
2269 : composite_kin_grad(composite_row, 1:2)
2270 : END IF
2271 : ELSE
2272 : IF (use_atom_composite_density) THEN
2273 : cross_density_adjoint(1) = 0.5_dp* &
2274 : SUM(composite_density_grad(composite_row, :))
2275 : END IF
2276 : IF (use_atom_composite_gradient) THEN
2277 : DO idir = 1, 3
2278 : cross_grad_adjoint(idir, 1) = 0.5_dp* &
2279 : SUM(composite_grad_grad(composite_row, idir, :))
2280 : END DO
2281 : END IF
2282 : IF (use_atom_composite_tau) THEN
2283 : cross_kin_adjoint(1) = 0.5_dp* &
2284 : SUM(composite_kin_grad(composite_row, :))
2285 : END IF
2286 : END IF
2287 : fractional = 0.0_dp
2288 : DO idir = 1, 3
2289 : DO jdir = 1, 3
2290 : fractional(idir) = fractional(idir) + cell%h_inv(idir, jdir)* &
2291 : (composite_grid_coords(jdir, composite_row) - &
2292 : particle_set(iatom)%r(jdir))
2293 : END DO
2294 : END DO
2295 : CALL atom_grid_image_bounds(cell, fractional, cross_cutoff, image_shell, &
2296 : image_lower, image_upper)
2297 : DO image_i3 = image_lower(3), image_upper(3)
2298 : DO image_i2 = image_lower(2), image_upper(2)
2299 : DO image_i1 = image_lower(1), image_upper(1)
2300 : image_shift = [image_i1, image_i2, image_i3]
2301 : IF (target_atom == iatom .AND. ALL(image_shift == 0)) CYCLE
2302 : image_translation = MATMUL( &
2303 : cell%hmat, REAL(image_shift, dp))
2304 : cross_displacement = &
2305 : composite_grid_coords(:, composite_row) - &
2306 : particle_set(iatom)%r - image_translation
2307 : ! Reject inactive images before allocating interpolation scratch.
2308 : IF (SQRT(SUM(cross_displacement**2)) > cross_cutoff) CYCLE
2309 : CALL add_gapw_atom_grid_interpolation_adjoint( &
2310 : grid_atom, harmonics, cross_displacement, cross_cutoff, &
2311 : nspins, cross_density_adjoint, cross_grad_adjoint, &
2312 : cross_kin_adjoint, vxc_h_local, vxc_s_local, vxg_h_local, vxg_s_local, &
2313 : vtau_h_local, vtau_s_local)
2314 : END DO
2315 : END DO
2316 : END DO
2317 : END DO
2318 : !$OMP END DO
2319 : !$OMP CRITICAL(skala_atom_composite_adjoint_reduction)
2320 : vxc_h = vxc_h + vxc_h_local
2321 : vxc_s = vxc_s + vxc_s_local
2322 : vxg_h = vxg_h + vxg_h_local
2323 : vxg_s = vxg_s + vxg_s_local
2324 : vtau_h = vtau_h + vtau_h_local
2325 : vtau_s = vtau_s + vtau_s_local
2326 : !$OMP END CRITICAL(skala_atom_composite_adjoint_reduction)
2327 : DEALLOCATE (vxc_h_local, vxc_s_local, vxg_h_local, vxg_s_local, vtau_h_local, vtau_s_local)
2328 : !$OMP END PARALLEL
2329 : END IF
2330 :
2331 : ! Model rows are distributed by target atom, while CP2K stores each
2332 : ! one-center matrix on the rank owning its source atom. Sum the exact
2333 : ! interpolation transpose before forming that matrix.
2334 475956 : CALL para_env%sum(vxc_h)
2335 475956 : CALL para_env%sum(vxc_s)
2336 1858356 : CALL para_env%sum(vxg_h)
2337 1858356 : CALL para_env%sum(vxg_s)
2338 475956 : CALL para_env%sum(vtau_h)
2339 475956 : CALL para_env%sum(vtau_s)
2340 252 : IF (.NOT. source_matrix_local) CYCLE
2341 :
2342 : one_center_rho_grad_field_contraction = &
2343 : one_center_rho_grad_field_contraction + SUM(vxc_h*(rho_h - rho_s)) + &
2344 583578 : SUM(vxg_h*(drho_h(1:3, :, :, :) - drho_s(1:3, :, :, :)))
2345 : one_center_density_field_contraction = one_center_density_field_contraction + &
2346 119052 : SUM(vxc_h*(rho_h - rho_s))
2347 : one_center_gradient_field_contraction = one_center_gradient_field_contraction + &
2348 : SUM(vxg_h*(drho_h(1:3, :, :, :) - &
2349 464652 : drho_s(1:3, :, :, :)))
2350 : one_center_tau_field_contraction = one_center_tau_field_contraction + &
2351 119052 : SUM(vtau_h*(tau_h - tau_s))
2352 :
2353 0 : ALLOCATE (composite_int_h(SIZE(int_hh(1)%r_coef, 1), &
2354 : SIZE(int_hh(1)%r_coef, 2), nspins), &
2355 0 : composite_int_s(SIZE(int_ss(1)%r_coef, 1), &
2356 1134 : SIZE(int_ss(1)%r_coef, 2), nspins))
2357 252 : DO ispin = 1, nspins
2358 29358 : composite_int_h(:, :, ispin) = int_hh(ispin)%r_coef
2359 29358 : composite_int_s(:, :, ispin) = int_ss(ispin)%r_coef
2360 29358 : int_hh(ispin)%r_coef = 0.0_dp
2361 29484 : int_ss(ispin)%r_coef = 0.0_dp
2362 : END DO
2363 : CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
2364 126 : grid_atom, basis_1c, harmonics, nspins)
2365 252 : DO ispin = 1, nspins
2366 : one_center_density_matrix_contraction = &
2367 : one_center_density_matrix_contraction + &
2368 : contract_one_center_matrix(cpc_h(ispin)%r_coef, &
2369 : int_hh(ispin)%r_coef, &
2370 : tau_basis_cache%n2oindex) - &
2371 : contract_one_center_matrix(cpc_s(ispin)%r_coef, &
2372 : int_ss(ispin)%r_coef, &
2373 126 : tau_basis_cache%n2oindex)
2374 29358 : int_hh(ispin)%r_coef = 0.0_dp
2375 29484 : int_ss(ispin)%r_coef = 0.0_dp
2376 : END DO
2377 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
2378 126 : grid_atom, basis_1c, harmonics, nspins)
2379 252 : DO ispin = 1, nspins
2380 : one_center_rho_grad_matrix_contraction = &
2381 : one_center_rho_grad_matrix_contraction + &
2382 : contract_one_center_matrix(cpc_h(ispin)%r_coef, &
2383 : int_hh(ispin)%r_coef, &
2384 : tau_basis_cache%n2oindex) - &
2385 : contract_one_center_matrix(cpc_s(ispin)%r_coef, &
2386 : int_ss(ispin)%r_coef, &
2387 252 : tau_basis_cache%n2oindex)
2388 : END DO
2389 126 : CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, tau_basis_cache, nspins)
2390 252 : DO ispin = 1, nspins
2391 : one_center_matrix_contraction = one_center_matrix_contraction + &
2392 : contract_one_center_matrix(cpc_h(ispin)%r_coef, &
2393 : int_hh(ispin)%r_coef, &
2394 : tau_basis_cache%n2oindex) - &
2395 : contract_one_center_matrix(cpc_s(ispin)%r_coef, &
2396 : int_ss(ispin)%r_coef, &
2397 126 : tau_basis_cache%n2oindex)
2398 252 : IF (.NOT. atom_composite_reference) THEN
2399 0 : int_hh(ispin)%r_coef = composite_int_h(:, :, ispin)
2400 0 : int_ss(ispin)%r_coef = composite_int_s(:, :, ispin)
2401 : END IF
2402 : END DO
2403 412 : DEALLOCATE (composite_int_h, composite_int_s)
2404 : END DO
2405 452 : CALL release_tau_basis_cache(tau_basis_cache)
2406 : END DO
2407 : END IF
2408 264 : CALL para_env%sum(one_center_density_field_contraction)
2409 264 : CALL para_env%sum(one_center_density_matrix_contraction)
2410 264 : CALL para_env%sum(one_center_gradient_field_contraction)
2411 264 : CALL para_env%sum(one_center_matrix_contraction)
2412 264 : CALL para_env%sum(one_center_rho_grad_field_contraction)
2413 264 : CALL para_env%sum(one_center_rho_grad_matrix_contraction)
2414 264 : CALL para_env%sum(one_center_tau_field_contraction)
2415 : one_center_field_contraction = one_center_rho_grad_field_contraction + &
2416 264 : one_center_tau_field_contraction
2417 : one_center_gradient_matrix_contraction = one_center_rho_grad_matrix_contraction - &
2418 264 : one_center_density_matrix_contraction
2419 : one_center_tau_matrix_contraction = one_center_matrix_contraction - &
2420 264 : one_center_rho_grad_matrix_contraction
2421 917312 : feature_component_analytic(1) = SUM(composite_density_grad*composite_density)
2422 2751936 : feature_component_analytic(2) = SUM(composite_grad_grad*composite_grad)
2423 917312 : feature_component_analytic(3) = SUM(composite_kin_grad*composite_kin)
2424 1056 : feature_component_analytic(4) = SUM(feature_component_analytic(1:3))
2425 264 : CALL para_env%sum(feature_component_analytic)
2426 : one_center_tensor_contraction = feature_component_analytic(4) - &
2427 264 : smooth_input_contraction
2428 264 : IF (atom_composite_diagnostic) THEN
2429 0 : DO icomponent = 1, 4
2430 0 : SELECT CASE (icomponent)
2431 : CASE (1)
2432 0 : composite_density = (1.0_dp + feature_vxc_step)*composite_density
2433 : CASE (2)
2434 0 : composite_grad = (1.0_dp + feature_vxc_step)*composite_grad
2435 : CASE (3)
2436 0 : composite_kin = (1.0_dp + feature_vxc_step)*composite_kin
2437 : CASE (4)
2438 0 : composite_density = (1.0_dp + feature_vxc_step)*composite_density
2439 0 : composite_grad = (1.0_dp + feature_vxc_step)*composite_grad
2440 0 : composite_kin = (1.0_dp + feature_vxc_step)*composite_kin
2441 : END SELECT
2442 : CALL skala_gapw_atom_composite_energy( &
2443 : my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
2444 : composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
2445 0 : composite_local_grid_sizes, composite_local_atom_coords, feature_vxc_plus)
2446 0 : SELECT CASE (icomponent)
2447 : CASE (1)
2448 : composite_density = ((1.0_dp - feature_vxc_step)/ &
2449 0 : (1.0_dp + feature_vxc_step))*composite_density
2450 : CASE (2)
2451 : composite_grad = ((1.0_dp - feature_vxc_step)/ &
2452 0 : (1.0_dp + feature_vxc_step))*composite_grad
2453 : CASE (3)
2454 : composite_kin = ((1.0_dp - feature_vxc_step)/ &
2455 0 : (1.0_dp + feature_vxc_step))*composite_kin
2456 : CASE (4)
2457 : composite_density = ((1.0_dp - feature_vxc_step)/ &
2458 0 : (1.0_dp + feature_vxc_step))*composite_density
2459 : composite_grad = ((1.0_dp - feature_vxc_step)/ &
2460 0 : (1.0_dp + feature_vxc_step))*composite_grad
2461 : composite_kin = ((1.0_dp - feature_vxc_step)/ &
2462 0 : (1.0_dp + feature_vxc_step))*composite_kin
2463 : END SELECT
2464 : CALL skala_gapw_atom_composite_energy( &
2465 : my_xc_section, para_env, composite_density, composite_grad, composite_kin, &
2466 : composite_grid_coords, composite_grid_weights, composite_atomic_grid_weights, &
2467 0 : composite_local_grid_sizes, composite_local_atom_coords, feature_vxc_minus)
2468 0 : SELECT CASE (icomponent)
2469 : CASE (1)
2470 0 : composite_density = composite_density/(1.0_dp - feature_vxc_step)
2471 : CASE (2)
2472 0 : composite_grad = composite_grad/(1.0_dp - feature_vxc_step)
2473 : CASE (3)
2474 0 : composite_kin = composite_kin/(1.0_dp - feature_vxc_step)
2475 : CASE (4)
2476 0 : composite_density = composite_density/(1.0_dp - feature_vxc_step)
2477 0 : composite_grad = composite_grad/(1.0_dp - feature_vxc_step)
2478 0 : composite_kin = composite_kin/(1.0_dp - feature_vxc_step)
2479 : END SELECT
2480 : feature_component_fd(icomponent) = &
2481 0 : (feature_vxc_plus - feature_vxc_minus)/(2.0_dp*feature_vxc_step)
2482 : END DO
2483 0 : feature_vxc_analytic = feature_component_analytic(4)
2484 0 : feature_vxc_fd = feature_component_fd(4)
2485 0 : iw = cp_logger_get_default_io_unit()
2486 0 : IF (iw > 0) THEN
2487 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0)") &
2488 0 : "SKALA_GPW| Atom-composite reference components", atom_composite_components
2489 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2490 0 : "SKALA_GPW| Atom-composite reference electrons", atom_composite_nelec
2491 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2492 0 : "SKALA_GPW| Atom-composite reference XC energy", atom_composite_exc
2493 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2494 0 : "SKALA_GPW| Atom-composite feature VXC contraction", feature_vxc_analytic
2495 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2496 0 : "SKALA_GPW| Atom-composite feature finite difference", feature_vxc_fd
2497 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2498 0 : "SKALA_GPW| Atom-composite feature VXC error", &
2499 0 : feature_vxc_analytic - feature_vxc_fd
2500 : WRITE (UNIT=iw, FMT="(T2,A,3(1X,ES24.16))") &
2501 0 : "SKALA_GPW| Atom-composite smooth PW adjoint", smooth_input_contraction, &
2502 0 : smooth_grid_contraction, smooth_grid_contraction - smooth_input_contraction
2503 : WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
2504 0 : "SKALA_GPW| Atom-composite one-center adjoint", one_center_tensor_contraction, &
2505 0 : one_center_field_contraction, one_center_matrix_contraction, &
2506 0 : one_center_matrix_contraction - one_center_tensor_contraction
2507 : WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
2508 0 : "SKALA_GPW| Atom-composite one-center channels", &
2509 0 : one_center_rho_grad_field_contraction, one_center_rho_grad_matrix_contraction, &
2510 0 : one_center_tau_field_contraction, one_center_tau_matrix_contraction
2511 : WRITE (UNIT=iw, FMT="(T2,A,4(1X,ES24.16))") &
2512 0 : "SKALA_GPW| Atom-composite one-center rho-gradient", &
2513 0 : one_center_density_field_contraction, one_center_density_matrix_contraction, &
2514 0 : one_center_gradient_field_contraction, one_center_gradient_matrix_contraction
2515 0 : DO icomponent = 1, 3
2516 : WRITE (UNIT=iw, FMT="(T2,A,1X,I0,3(1X,ES24.16))") &
2517 0 : "SKALA_GPW| Atom-composite component VXC", icomponent, &
2518 0 : feature_component_analytic(icomponent), feature_component_fd(icomponent), &
2519 0 : feature_component_analytic(icomponent) - feature_component_fd(icomponent)
2520 : END DO
2521 : END IF
2522 : END IF
2523 264 : IF (atom_composite_reference) THEN
2524 264 : exc1 = atom_composite_exc
2525 264 : IF (native_grid_diagnostics) THEN
2526 30 : IF (composite_nflat > 0) THEN
2527 119540 : composite_density_min = MINVAL(composite_density)
2528 119540 : composite_density_max = MAXVAL(composite_density)
2529 119540 : composite_kin_min = MINVAL(composite_kin)
2530 119540 : composite_kin_max = MAXVAL(composite_kin)
2531 358620 : composite_grad_max = MAXVAL(ABS(composite_grad))
2532 : ELSE
2533 10 : composite_density_min = HUGE(1.0_dp)
2534 10 : composite_density_max = -HUGE(1.0_dp)
2535 10 : composite_kin_min = HUGE(1.0_dp)
2536 10 : composite_kin_max = -HUGE(1.0_dp)
2537 10 : composite_grad_max = 0.0_dp
2538 : END IF
2539 : composite_tau_integral = &
2540 179250 : SUM(composite_grid_weights*SUM(composite_kin, DIM=2))
2541 30 : CALL para_env%min(composite_density_min)
2542 30 : CALL para_env%max(composite_density_max)
2543 30 : CALL para_env%min(composite_kin_min)
2544 30 : CALL para_env%max(composite_kin_max)
2545 30 : CALL para_env%max(composite_grad_max)
2546 30 : CALL para_env%sum(composite_tau_integral)
2547 : END IF
2548 264 : iw = cp_logger_get_default_io_unit()
2549 264 : IF (iw > 0) THEN
2550 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2551 132 : "SKALA_GPW| Active atom-composite XC energy", atom_composite_exc
2552 132 : IF (native_grid_diagnostics) THEN
2553 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2554 15 : "SKALA_GPW| Active atom-composite electrons", atom_composite_nelec
2555 : WRITE (UNIT=iw, FMT="(T2,A,2(1X,ES24.16))") &
2556 15 : "SKALA_GPW| Active atom-composite density range", &
2557 30 : composite_density_min, composite_density_max
2558 : WRITE (UNIT=iw, FMT="(T2,A,2(1X,ES24.16))") &
2559 15 : "SKALA_GPW| Active atom-composite tau range", &
2560 30 : composite_kin_min, composite_kin_max
2561 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2562 15 : "SKALA_GPW| Active atom-composite tau integral", &
2563 30 : composite_tau_integral
2564 : WRITE (UNIT=iw, FMT="(T2,A,1X,ES24.16)") &
2565 15 : "SKALA_GPW| Active atom-composite max gradient", &
2566 30 : composite_grad_max
2567 : END IF
2568 : END IF
2569 : END IF
2570 264 : CALL xc_rho_set_release(smooth_rho_set, pw_pool=auxbas_pw_pool)
2571 0 : DEALLOCATE (composite_atomic_grid_sizes, composite_atom_kind, &
2572 0 : composite_atom_kind_index, composite_atom_start, composite_atom_end, &
2573 0 : composite_atom_coords, composite_local_atoms, composite_local_grid_sizes, &
2574 0 : composite_local_atom_coords, composite_grid_atom, &
2575 0 : composite_partition_weights, composite_partition_atom_coords, &
2576 0 : composite_distances, composite_density, composite_grad, composite_kin, &
2577 0 : composite_smooth_density_cache, composite_smooth_gradient_cache, &
2578 0 : composite_smooth_kin_cache, &
2579 0 : composite_density_grad, composite_grad_grad, composite_kin_grad, &
2580 0 : composite_grid_coords, composite_grid_weights, &
2581 264 : composite_base_grid_weights, composite_atomic_grid_weights)
2582 264 : IF (lsd) THEN
2583 0 : DEALLOCATE (composite_smooth_rhoa, composite_smooth_rhob, &
2584 42 : composite_smooth_tau_a, composite_smooth_tau_b)
2585 168 : DO idir = 1, 3
2586 0 : DEALLOCATE (composite_smooth_drhoa(idir)%array, &
2587 168 : composite_smooth_drhob(idir)%array)
2588 : END DO
2589 : ELSE
2590 222 : DEALLOCATE (composite_smooth_rho, composite_smooth_tau)
2591 888 : DO idir = 1, 3
2592 888 : DEALLOCATE (composite_smooth_drho(idir)%array)
2593 : END DO
2594 : END IF
2595 : END IF
2596 :
2597 28632 : IF (.NOT. atom_composite_reference) CALL para_env%sum(exc1)
2598 :
2599 28632 : IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
2600 28632 : IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
2601 28632 : IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
2602 28632 : IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
2603 :
2604 28632 : IF (gradient_f) THEN
2605 19778 : IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
2606 19778 : IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
2607 19778 : IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
2608 19778 : IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
2609 : END IF
2610 :
2611 28632 : IF (tau_f) THEN
2612 926 : IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
2613 926 : IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
2614 926 : IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
2615 926 : IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
2616 : END IF
2617 :
2618 : END IF !xc_none
2619 :
2620 32836 : CALL timestop(handle)
2621 :
2622 5746300 : END SUBROUTINE calculate_vxc_atom
2623 :
2624 : ! **************************************************************************************************
2625 : !> \brief Add the GAPW one-center correction to CDFT values and operators.
2626 : !> \param qs_env Quickstep environment
2627 : !> \param energy_only skip construction of the CDFT one-center operator
2628 : !> \param calculate_forces evaluate explicit derivatives of the partition weights
2629 : !> \param values constraint values from the hard-minus-soft one-center densities
2630 : !> \param electronic_charge optional one-center corrections to atomic populations
2631 : !> \param operator_group optional group for which to build the unscaled weight operator
2632 : !> \param rho_atom_operator_set optional destination for the one-center operator integrals
2633 : ! **************************************************************************************************
2634 456 : SUBROUTINE gapw_cdft_one_center(qs_env, energy_only, calculate_forces, values, &
2635 456 : electronic_charge, operator_group, rho_atom_operator_set)
2636 : TYPE(qs_environment_type), POINTER :: qs_env
2637 : LOGICAL, INTENT(IN) :: energy_only, calculate_forces
2638 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: values
2639 : REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT), &
2640 : OPTIONAL :: electronic_charge
2641 : INTEGER, INTENT(IN), OPTIONAL :: operator_group
2642 : TYPE(rho_atom_type), DIMENSION(:), POINTER, &
2643 : OPTIONAL :: rho_atom_operator_set
2644 :
2645 : INTEGER :: atom, channel, ia, iat, igroup, ikind, &
2646 : ir, natom, natom_kind, nspins
2647 : INTEGER, DIMENSION(2) :: atom_bounds
2648 456 : INTEGER, DIMENSION(:), POINTER :: atom_list
2649 : LOGICAL :: lsd, paw_atom
2650 : REAL(KIND=dp) :: delta_density, point_factor, spin_factor
2651 456 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: atomic_weights, group_weights
2652 456 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: explicit_derivative, &
2653 456 : group_point_derivative
2654 456 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: group_atom_derivative
2655 : REAL(KIND=dp), DIMENSION(3) :: point
2656 456 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: rho_h, rho_s
2657 456 : REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s
2658 456 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: vlocal_h, vlocal_s
2659 456 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2660 : TYPE(cdft_control_type), POINTER :: cdft_control
2661 456 : TYPE(cdft_point_context_type) :: context
2662 : TYPE(dft_control_type), POINTER :: dft_control
2663 : TYPE(grid_atom_type), POINTER :: grid_atom
2664 : TYPE(gto_basis_set_type), POINTER :: basis_1c
2665 : TYPE(harmonics_atom_type), POINTER :: harmonics
2666 : TYPE(mp_para_env_type), POINTER :: para_env
2667 456 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2668 456 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
2669 456 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2670 456 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
2671 456 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
2672 456 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: operator_atom_set, rho_atom_set
2673 : TYPE(rho_atom_type), POINTER :: operator_atom, rho_atom
2674 :
2675 456 : NULLIFY (atom_list, atomic_kind_set, basis_1c, cdft_control, dft_control, force, &
2676 456 : grid_atom, harmonics, int_hh, int_ss, para_env, particle_set, r_h, r_s, &
2677 456 : dr_h, dr_s, r_h_d, r_s_d, rho_h, rho_s, drho_h, drho_s, &
2678 456 : operator_atom, operator_atom_set, rho_atom, rho_atom_set, qs_kind_set, &
2679 456 : vlocal_h, vlocal_s)
2680 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, dft_control=dft_control, &
2681 : force=force, natom=natom, para_env=para_env, particle_set=particle_set, &
2682 456 : qs_kind_set=qs_kind_set, rho_atom_set=rho_atom_set)
2683 456 : CPASSERT(ASSOCIATED(atomic_kind_set))
2684 456 : CPASSERT(ASSOCIATED(dft_control))
2685 456 : CPASSERT(ASSOCIATED(para_env))
2686 456 : CPASSERT(ASSOCIATED(particle_set))
2687 456 : CPASSERT(ASSOCIATED(qs_kind_set))
2688 456 : CPASSERT(ASSOCIATED(rho_atom_set))
2689 456 : operator_atom_set => rho_atom_set
2690 456 : IF (PRESENT(rho_atom_operator_set)) operator_atom_set => rho_atom_operator_set
2691 456 : CPASSERT(ASSOCIATED(operator_atom_set))
2692 456 : cdft_control => dft_control%qs_control%cdft_control
2693 456 : CPASSERT(ASSOCIATED(cdft_control))
2694 456 : nspins = dft_control%nspins
2695 456 : lsd = dft_control%lsd
2696 456 : CPASSERT(SIZE(values) == SIZE(cdft_control%group))
2697 456 : IF (PRESENT(operator_group)) THEN
2698 4 : CPASSERT(operator_group >= 1 .AND. operator_group <= SIZE(cdft_control%group))
2699 : END IF
2700 456 : IF (PRESENT(electronic_charge)) THEN
2701 76 : CPASSERT(SIZE(electronic_charge, 1) == natom)
2702 76 : CPASSERT(SIZE(electronic_charge, 2) == nspins)
2703 : END IF
2704 :
2705 456 : CALL cdft_point_context_create(qs_env, context, calculate_forces)
2706 : ALLOCATE (group_weights(context%ngroup), group_point_derivative(3, context%ngroup), &
2707 : group_atom_derivative(3, natom, context%ngroup), &
2708 4560 : explicit_derivative(3, natom))
2709 608 : IF (PRESENT(electronic_charge)) ALLOCATE (atomic_weights(natom))
2710 1000 : values = 0.0_dp
2711 456 : explicit_derivative = 0.0_dp
2712 1004 : IF (PRESENT(electronic_charge)) electronic_charge = 0.0_dp
2713 :
2714 1068 : DO ikind = 1, SIZE(atomic_kind_set)
2715 612 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom_kind)
2716 : CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom, grid_atom=grid_atom, &
2717 612 : harmonics=harmonics)
2718 612 : IF (.NOT. paw_atom) CYCLE
2719 612 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
2720 612 : CPASSERT(ASSOCIATED(grid_atom))
2721 612 : CPASSERT(ASSOCIATED(harmonics))
2722 612 : CPASSERT(ASSOCIATED(basis_1c))
2723 : ALLOCATE (vlocal_h(grid_atom%ng_sphere, grid_atom%nr, nspins), &
2724 5508 : vlocal_s(grid_atom%ng_sphere, grid_atom%nr, nspins))
2725 :
2726 612 : atom_bounds = get_limit(natom_kind, para_env%num_pe, para_env%mepos)
2727 1131 : DO iat = atom_bounds(1), atom_bounds(2)
2728 519 : atom = atom_list(iat)
2729 519 : rho_atom => rho_atom_set(atom)
2730 519 : NULLIFY (r_h, r_s)
2731 519 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
2732 519 : CALL reallocate(rho_h, 1, grid_atom%ng_sphere, 1, grid_atom%nr, 1, nspins)
2733 519 : CALL reallocate(rho_s, 1, grid_atom%ng_sphere, 1, grid_atom%nr, 1, nspins)
2734 1811729 : rho_h = 0.0_dp
2735 1811729 : rho_s = 0.0_dp
2736 26469 : DO ir = 1, grid_atom%nr
2737 : CALL calc_rho_angular(grid_atom, harmonics, nspins, .FALSE., ir, r_h, r_s, &
2738 26469 : rho_h, rho_s, dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
2739 : END DO
2740 1811729 : vlocal_h = 0.0_dp
2741 1811729 : vlocal_s = 0.0_dp
2742 :
2743 26469 : DO ir = 1, grid_atom%nr
2744 1323969 : DO ia = 1, grid_atom%ng_sphere
2745 : point(1) = particle_set(atom)%r(1) + grid_atom%rad(ir)* &
2746 1297500 : grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
2747 : point(2) = particle_set(atom)%r(2) + grid_atom%rad(ir)* &
2748 1297500 : grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
2749 1297500 : point(3) = particle_set(atom)%r(3) + grid_atom%rad(ir)*grid_atom%cos_pol(ia)
2750 1297500 : IF (PRESENT(electronic_charge)) THEN
2751 : CALL cdft_point_weights(context, point, group_weights, &
2752 : group_point_derivative, group_atom_derivative, &
2753 247500 : atomic_weights)
2754 : ELSE
2755 : CALL cdft_point_weights(context, point, group_weights, &
2756 1050000 : group_point_derivative, group_atom_derivative)
2757 : END IF
2758 3098450 : DO channel = 1, nspins
2759 1775000 : delta_density = rho_h(ia, ir, channel) - rho_s(ia, ir, channel)
2760 1775000 : IF (PRESENT(electronic_charge)) THEN
2761 : electronic_charge(:, channel) = electronic_charge(:, channel) + &
2762 : grid_atom%weight(ia, ir)*atomic_weights* &
2763 1830000 : delta_density
2764 : END IF
2765 1775000 : point_factor = 0.0_dp
2766 3990000 : DO igroup = 1, context%ngroup
2767 : spin_factor = cdft_spin_factor( &
2768 2215000 : cdft_control%group(igroup)%constraint_type, channel, lsd)
2769 2215000 : IF (PRESENT(operator_group)) THEN
2770 10000 : IF (igroup == operator_group) THEN
2771 10000 : point_factor = point_factor + group_weights(igroup)
2772 : END IF
2773 : ELSE
2774 : point_factor = point_factor + cdft_control%strength(igroup)* &
2775 2205000 : group_weights(igroup)*spin_factor
2776 : END IF
2777 : values(igroup) = values(igroup) + grid_atom%weight(ia, ir)* &
2778 2215000 : group_weights(igroup)*delta_density*spin_factor
2779 3990000 : IF (calculate_forces) THEN
2780 : explicit_derivative(:, :) = &
2781 : explicit_derivative + grid_atom%weight(ia, ir)* &
2782 : cdft_control%strength(igroup)*delta_density* &
2783 367500 : spin_factor*group_atom_derivative(:, :, igroup)
2784 : explicit_derivative(:, atom) = explicit_derivative(:, atom) + &
2785 : grid_atom%weight(ia, ir)* &
2786 : cdft_control%strength(igroup)*delta_density* &
2787 150000 : spin_factor*group_point_derivative(:, igroup)
2788 : END IF
2789 : END DO
2790 1775000 : vlocal_h(ia, ir, channel) = grid_atom%weight(ia, ir)*point_factor
2791 3072500 : vlocal_s(ia, ir, channel) = vlocal_h(ia, ir, channel)
2792 : END DO
2793 : END DO
2794 : END DO
2795 :
2796 1131 : IF (.NOT. energy_only) THEN
2797 380 : NULLIFY (int_hh, int_ss)
2798 380 : operator_atom => operator_atom_set(atom)
2799 380 : CALL get_rho_atom(rho_atom=operator_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
2800 : CALL gaVxcgb_noGC(vlocal_h, vlocal_s, int_hh, int_ss, grid_atom, &
2801 380 : basis_1c, harmonics, nspins)
2802 : END IF
2803 : END DO
2804 1680 : DEALLOCATE (vlocal_h, vlocal_s)
2805 : END DO
2806 :
2807 1544 : CALL para_env%sum(values)
2808 456 : CALL para_env%sum(explicit_derivative)
2809 1552 : IF (PRESENT(electronic_charge)) CALL para_env%sum(electronic_charge)
2810 456 : IF (calculate_forces .AND. ASSOCIATED(force) .AND. para_env%is_source()) THEN
2811 9 : DO ikind = 1, SIZE(atomic_kind_set)
2812 5 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom_kind)
2813 18 : DO iat = 1, natom_kind
2814 9 : atom = atom_list(iat)
2815 : force(ikind)%rho_elec(:, iat) = force(ikind)%rho_elec(:, iat) + &
2816 41 : explicit_derivative(:, atom)
2817 : END DO
2818 : END DO
2819 : END IF
2820 :
2821 456 : IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
2822 456 : IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
2823 456 : IF (ALLOCATED(atomic_weights)) DEALLOCATE (atomic_weights)
2824 456 : DEALLOCATE (explicit_derivative, group_atom_derivative, group_point_derivative, group_weights)
2825 912 : CALL cdft_point_context_release(context)
2826 :
2827 : CONTAINS
2828 :
2829 : ! **************************************************************************************************
2830 : !> \brief ...
2831 : !> \param constraint_type ...
2832 : !> \param channel ...
2833 : !> \param lsd ...
2834 : !> \return ...
2835 : ! **************************************************************************************************
2836 2215000 : FUNCTION cdft_spin_factor(constraint_type, channel, lsd) RESULT(factor)
2837 : INTEGER, INTENT(IN) :: constraint_type, channel
2838 : LOGICAL, INTENT(IN) :: lsd
2839 : REAL(KIND=dp) :: factor
2840 :
2841 2215000 : SELECT CASE (constraint_type)
2842 : CASE (cdft_charge_constraint)
2843 0 : factor = 1.0_dp
2844 : CASE (cdft_magnetization_constraint)
2845 0 : CPASSERT(lsd)
2846 0 : factor = MERGE(1.0_dp, -1.0_dp, channel == 1)
2847 : CASE (cdft_alpha_constraint)
2848 440000 : CPASSERT(lsd)
2849 440000 : factor = MERGE(1.0_dp, 0.0_dp, channel == 1)
2850 : CASE (cdft_beta_constraint)
2851 440000 : CPASSERT(lsd)
2852 440000 : factor = MERGE(1.0_dp, 0.0_dp, channel == 2)
2853 : CASE DEFAULT
2854 2215000 : CPABORT("Unknown CDFT constraint type.")
2855 : END SELECT
2856 2215000 : END FUNCTION cdft_spin_factor
2857 :
2858 : END SUBROUTINE gapw_cdft_one_center
2859 :
2860 : ! **************************************************************************************************
2861 : !> \brief Contract a compact one-center density matrix with an integral in the padded old basis.
2862 : !> \param density_matrix ...
2863 : !> \param integral_matrix ...
2864 : !> \param new_to_old ...
2865 : !> \return ...
2866 : ! **************************************************************************************************
2867 756 : FUNCTION contract_one_center_matrix(density_matrix, integral_matrix, new_to_old) RESULT(value)
2868 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: density_matrix, integral_matrix
2869 : INTEGER, DIMENSION(:), INTENT(IN) :: new_to_old
2870 : REAL(KIND=dp) :: value
2871 :
2872 : INTEGER :: ibas, jbas, nbas
2873 :
2874 756 : nbas = SIZE(density_matrix, 1)
2875 756 : CPASSERT(SIZE(density_matrix, 2) == nbas)
2876 756 : CPASSERT(SIZE(new_to_old) >= nbas)
2877 5988 : CPASSERT(MINVAL(new_to_old(1:nbas)) >= 1)
2878 5988 : CPASSERT(MAXVAL(new_to_old(1:nbas)) <= SIZE(integral_matrix, 1))
2879 5988 : CPASSERT(MAXVAL(new_to_old(1:nbas)) <= SIZE(integral_matrix, 2))
2880 :
2881 756 : value = 0.0_dp
2882 5988 : DO jbas = 1, nbas
2883 73356 : DO ibas = 1, nbas
2884 : value = value + density_matrix(ibas, jbas)* &
2885 72600 : integral_matrix(new_to_old(ibas), new_to_old(jbas))
2886 : END DO
2887 : END DO
2888 :
2889 756 : END FUNCTION contract_one_center_matrix
2890 :
2891 : ! **************************************************************************************************
2892 : !> \brief Replicate a distributed real-space field for atom-grid interpolation.
2893 : !> \param local_values ...
2894 : !> \param pw_grid ...
2895 : !> \param group ...
2896 : !> \param global_values ...
2897 : ! **************************************************************************************************
2898 1530 : SUBROUTINE gather_native_grid_field(local_values, pw_grid, group, global_values)
2899 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN), &
2900 : POINTER :: local_values
2901 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
2902 : TYPE(mp_para_env_type), INTENT(IN) :: group
2903 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT), &
2904 : POINTER :: global_values
2905 :
2906 : INTEGER, DIMENSION(2, 3) :: bo
2907 :
2908 1530 : CPASSERT(ASSOCIATED(local_values))
2909 1530 : CPASSERT(ASSOCIATED(pw_grid))
2910 1530 : CPASSERT(.NOT. ASSOCIATED(global_values))
2911 15300 : bo = pw_grid%bounds_local
2912 : ALLOCATE (global_values(pw_grid%bounds(1, 1):pw_grid%bounds(2, 1), &
2913 : pw_grid%bounds(1, 2):pw_grid%bounds(2, 2), &
2914 7650 : pw_grid%bounds(1, 3):pw_grid%bounds(2, 3)))
2915 12411000 : global_values = 0.0_dp
2916 : global_values(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)) = &
2917 12986670 : local_values
2918 24820470 : CALL group%sum(global_values)
2919 :
2920 1530 : END SUBROUTINE gather_native_grid_field
2921 :
2922 : ! **************************************************************************************************
2923 : !> \brief Build the tensor-product interpolation stencil for one Cartesian point.
2924 : !> \param stencil ...
2925 : !> \param pw_grid ...
2926 : !> \param cell ...
2927 : !> \param point ...
2928 : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
2929 : !> \param indices_only skip interpolation weights when only grid indices are needed
2930 : ! **************************************************************************************************
2931 71819520 : SUBROUTINE create_native_grid_interpolation_stencil(stencil, pw_grid, cell, point, &
2932 : wrap_auxiliary_cell, indices_only)
2933 : TYPE(native_grid_interpolation_stencil_type), &
2934 : INTENT(OUT) :: stencil
2935 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
2936 : TYPE(cell_type), INTENT(IN), POINTER :: cell
2937 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: point
2938 : LOGICAL, INTENT(IN), OPTIONAL :: wrap_auxiliary_cell, indices_only
2939 :
2940 : INTEGER :: idir, inode, relative_index
2941 : INTEGER, DIMENSION(3) :: base
2942 : LOGICAL :: build_weights, wrap_grid
2943 : REAL(KIND=dp), DIMENSION(3) :: fraction, relative
2944 :
2945 608640 : CPASSERT(ASSOCIATED(pw_grid))
2946 608640 : CPASSERT(ASSOCIATED(cell))
2947 608640 : stencil%active = .FALSE.
2948 24345600 : stencil%valid = .FALSE.
2949 24345600 : stencil%weight = 0.0_dp
2950 608640 : build_weights = .TRUE.
2951 608640 : IF (PRESENT(indices_only)) build_weights = .NOT. indices_only
2952 2299560 : wrap_grid = ANY(cell%perd == 0)
2953 608640 : IF (PRESENT(wrap_auxiliary_cell)) wrap_grid = wrap_auxiliary_cell
2954 7912320 : relative = MATMUL(pw_grid%dh_inv, point)
2955 2434560 : DO idir = 1, 3
2956 1825920 : IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
2957 1825920 : relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
2958 0 : ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
2959 : relative(idir) >= REAL(pw_grid%npts(idir) - &
2960 : native_grid_interp_offset_min, KIND=dp)) THEN
2961 0 : RETURN
2962 : END IF
2963 1825920 : base(idir) = FLOOR(relative(idir))
2964 1825920 : FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
2965 1825920 : IF (build_weights) THEN
2966 451140 : CALL native_grid_lagrange_weights(FRACTION(idir), stencil%weight(:, idir))
2967 : END IF
2968 24345600 : DO inode = 1, native_grid_interp_npts
2969 21911040 : relative_index = base(idir) + native_grid_interp_offset_min + inode - 1
2970 21911040 : IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
2971 21911040 : relative_index = MODULO(relative_index, pw_grid%npts(idir))
2972 21911040 : stencil%valid(inode, idir) = .TRUE.
2973 0 : ELSE IF (relative_index >= 0 .AND. relative_index < pw_grid%npts(idir)) THEN
2974 0 : stencil%valid(inode, idir) = .TRUE.
2975 : END IF
2976 23736960 : stencil%relative_index(inode, idir) = relative_index
2977 : END DO
2978 : END DO
2979 608640 : stencil%active = .TRUE.
2980 :
2981 : END SUBROUTINE create_native_grid_interpolation_stencil
2982 :
2983 : ! **************************************************************************************************
2984 : !> \brief Interpolate density, gradient, and kinetic-density fields in one stencil traversal.
2985 : !> \param density ...
2986 : !> \param grad_x ...
2987 : !> \param grad_y ...
2988 : !> \param grad_z ...
2989 : !> \param kin ...
2990 : !> \param stencil ...
2991 : !> \param density_value ...
2992 : !> \param grad_value ...
2993 : !> \param kin_value ...
2994 : ! **************************************************************************************************
2995 563260 : SUBROUTINE interpolate_native_grid_fields(density, grad_x, grad_y, grad_z, kin, stencil, &
2996 : density_value, grad_value, kin_value)
2997 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: density, grad_x, grad_y, grad_z, kin
2998 : TYPE(native_grid_interpolation_stencil_type), &
2999 : INTENT(IN) :: stencil
3000 : REAL(KIND=dp), INTENT(OUT) :: density_value
3001 : REAL(KIND=dp), DIMENSION(3), INTENT(OUT) :: grad_value
3002 : REAL(KIND=dp), INTENT(OUT) :: kin_value
3003 :
3004 : INTEGER :: inode_x, inode_y, inode_z
3005 : INTEGER, DIMENSION(3) :: index, lower_bound
3006 : REAL(KIND=dp) :: coefficient
3007 :
3008 2253040 : CPASSERT(ALL(SHAPE(grad_x) == SHAPE(density)))
3009 2253040 : CPASSERT(ALL(SHAPE(grad_y) == SHAPE(density)))
3010 2253040 : CPASSERT(ALL(SHAPE(grad_z) == SHAPE(density)))
3011 2253040 : CPASSERT(ALL(SHAPE(kin) == SHAPE(density)))
3012 563260 : density_value = 0.0_dp
3013 563260 : grad_value = 0.0_dp
3014 563260 : kin_value = 0.0_dp
3015 563260 : IF (.NOT. stencil%active) RETURN
3016 : lower_bound = LBOUND(density)
3017 7322380 : DO inode_z = 1, native_grid_interp_npts
3018 6759120 : IF (.NOT. stencil%valid(inode_z, 3)) CYCLE
3019 6759120 : INDEX(3) = lower_bound(3) + stencil%relative_index(inode_z, 3)
3020 88431820 : DO inode_y = 1, native_grid_interp_npts
3021 81109440 : IF (.NOT. stencil%valid(inode_y, 2)) CYCLE
3022 81109440 : INDEX(2) = lower_bound(2) + stencil%relative_index(inode_y, 2)
3023 1061181840 : DO inode_x = 1, native_grid_interp_npts
3024 973313280 : IF (.NOT. stencil%valid(inode_x, 1)) CYCLE
3025 973313280 : INDEX(1) = lower_bound(1) + stencil%relative_index(inode_x, 1)
3026 : coefficient = stencil%weight(inode_x, 1)* &
3027 : stencil%weight(inode_y, 2)* &
3028 973313280 : stencil%weight(inode_z, 3)
3029 973313280 : density_value = density_value + coefficient*density(INDEX(1), INDEX(2), INDEX(3))
3030 973313280 : grad_value(1) = grad_value(1) + coefficient*grad_x(INDEX(1), INDEX(2), INDEX(3))
3031 973313280 : grad_value(2) = grad_value(2) + coefficient*grad_y(INDEX(1), INDEX(2), INDEX(3))
3032 973313280 : grad_value(3) = grad_value(3) + coefficient*grad_z(INDEX(1), INDEX(2), INDEX(3))
3033 1054422720 : kin_value = kin_value + coefficient*kin(INDEX(1), INDEX(2), INDEX(3))
3034 : END DO
3035 : END DO
3036 : END DO
3037 :
3038 : END SUBROUTINE interpolate_native_grid_fields
3039 :
3040 : ! **************************************************************************************************
3041 : !> \brief Group atom-grid rows by the disjoint PW tiles touched by their interpolation stencils.
3042 : !> \param pw_grid ...
3043 : !> \param cell ...
3044 : !> \param points atom-grid coordinates
3045 : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
3046 : !> \param tile_count number of tiles along each PW-grid direction
3047 : !> \param bin_offsets CSR offsets into bin_rows
3048 : !> \param bin_rows atom-grid rows touching each tile
3049 : ! **************************************************************************************************
3050 264 : SUBROUTINE build_native_grid_adjoint_bins(pw_grid, cell, points, wrap_auxiliary_cell, &
3051 : tile_count, bin_offsets, bin_rows)
3052 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
3053 : TYPE(cell_type), INTENT(IN), POINTER :: cell
3054 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: points
3055 : LOGICAL, INTENT(IN) :: wrap_auxiliary_cell
3056 : INTEGER, DIMENSION(3), INTENT(OUT) :: tile_count
3057 : INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(OUT) :: bin_offsets, bin_rows
3058 :
3059 : INTEGER :: candidate, ibin, idir, inode, irow, ix, &
3060 : iy, iz, nbin, ntouched, position
3061 264 : INTEGER, ALLOCATABLE, DIMENSION(:) :: bin_counts, bin_cursor, row_bin_count
3062 264 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: row_bins
3063 : INTEGER, DIMENSION(3) :: touched_count
3064 : INTEGER, DIMENSION(&
3065 : native_grid_adjoint_max_tiles_per_direction, 3) :: touched_tiles
3066 : TYPE(native_grid_interpolation_stencil_type) :: stencil
3067 :
3068 0 : CPASSERT(ASSOCIATED(pw_grid))
3069 264 : CPASSERT(ASSOCIATED(cell))
3070 264 : CPASSERT(SIZE(points, 1) == 3)
3071 : tile_count = (pw_grid%npts + native_grid_adjoint_tile_edge - 1)/ &
3072 1056 : native_grid_adjoint_tile_edge
3073 1056 : nbin = PRODUCT(tile_count)
3074 0 : ALLOCATE (row_bin_count(SIZE(points, 2)), &
3075 1276 : row_bins(native_grid_adjoint_max_bins_per_row, SIZE(points, 2)))
3076 264 : row_bin_count = 0
3077 264 : row_bins = 0
3078 : !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) &
3079 : !$OMP PRIVATE(candidate, idir, inode, ix, iy, iz, ntouched, stencil, &
3080 : !$OMP touched_count, touched_tiles) &
3081 264 : !$OMP SHARED(cell, points, pw_grid, row_bin_count, row_bins, tile_count, wrap_auxiliary_cell)
3082 : DO irow = 1, SIZE(points, 2)
3083 : CALL create_native_grid_interpolation_stencil( &
3084 : stencil, pw_grid, cell, points(:, irow), wrap_auxiliary_cell, indices_only=.TRUE.)
3085 : IF (.NOT. stencil%active) CYCLE
3086 : touched_count = 0
3087 : touched_tiles = 0
3088 : DO idir = 1, 3
3089 : DO inode = 1, native_grid_interp_npts
3090 : IF (.NOT. stencil%valid(inode, idir)) CYCLE
3091 : candidate = stencil%relative_index(inode, idir)/native_grid_adjoint_tile_edge + 1
3092 : IF (ALL(touched_tiles(1:touched_count(idir), idir) /= candidate)) THEN
3093 : touched_count(idir) = touched_count(idir) + 1
3094 : CPASSERT(touched_count(idir) <= SIZE(touched_tiles, 1))
3095 : touched_tiles(touched_count(idir), idir) = candidate
3096 : END IF
3097 : END DO
3098 : END DO
3099 : ntouched = 0
3100 : DO iz = 1, touched_count(3)
3101 : DO iy = 1, touched_count(2)
3102 : DO ix = 1, touched_count(1)
3103 : ntouched = ntouched + 1
3104 : CPASSERT(ntouched <= native_grid_adjoint_max_bins_per_row)
3105 : row_bins(ntouched, irow) = 1 + touched_tiles(ix, 1) - 1 + tile_count(1)*( &
3106 : touched_tiles(iy, 2) - 1 + tile_count(2)*( &
3107 : touched_tiles(iz, 3) - 1))
3108 : END DO
3109 : END DO
3110 : END DO
3111 : row_bin_count(irow) = ntouched
3112 : END DO
3113 : !$OMP END PARALLEL DO
3114 :
3115 1584 : ALLOCATE (bin_counts(nbin), bin_cursor(nbin), bin_offsets(nbin + 1))
3116 264 : bin_counts = 0
3117 458524 : DO irow = 1, SIZE(points, 2)
3118 916784 : DO ibin = 1, row_bin_count(irow)
3119 916520 : bin_counts(row_bins(ibin, irow)) = bin_counts(row_bins(ibin, irow)) + 1
3120 : END DO
3121 : END DO
3122 264 : bin_offsets(1) = 1
3123 528 : DO ibin = 1, nbin
3124 528 : bin_offsets(ibin + 1) = bin_offsets(ibin) + bin_counts(ibin)
3125 : END DO
3126 770 : ALLOCATE (bin_rows(bin_offsets(nbin + 1) - 1))
3127 528 : bin_cursor(:) = bin_offsets(1:nbin)
3128 458524 : DO irow = 1, SIZE(points, 2)
3129 916784 : DO ibin = 1, row_bin_count(irow)
3130 458260 : candidate = row_bins(ibin, irow)
3131 458260 : position = bin_cursor(candidate)
3132 458260 : bin_rows(position) = irow
3133 916520 : bin_cursor(candidate) = position + 1
3134 : END DO
3135 : END DO
3136 264 : DEALLOCATE (bin_counts, bin_cursor, row_bin_count, row_bins)
3137 :
3138 31944 : END SUBROUTINE build_native_grid_adjoint_bins
3139 :
3140 : ! **************************************************************************************************
3141 : !> \brief Return the inclusive PW-grid bounds owned by one linear tile index.
3142 : !> \param pw_grid ...
3143 : !> \param tile_index linear tile index
3144 : !> \param tile_count number of tiles along each PW-grid direction
3145 : !> \param tile_lower zero-based lower grid index
3146 : !> \param tile_upper zero-based upper grid index
3147 : ! **************************************************************************************************
3148 264 : SUBROUTINE native_grid_adjoint_tile_bounds(pw_grid, tile_index, tile_count, &
3149 : tile_lower, tile_upper)
3150 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
3151 : INTEGER, INTENT(IN) :: tile_index
3152 : INTEGER, DIMENSION(3), INTENT(IN) :: tile_count
3153 : INTEGER, DIMENSION(3), INTENT(OUT) :: tile_lower, tile_upper
3154 :
3155 : INTEGER :: linear_tile
3156 : INTEGER, DIMENSION(3) :: expected_tile_count, tile_coord
3157 :
3158 264 : CPASSERT(ASSOCIATED(pw_grid))
3159 : expected_tile_count = (pw_grid%npts + native_grid_adjoint_tile_edge - 1)/ &
3160 1056 : native_grid_adjoint_tile_edge
3161 1056 : CPASSERT(ALL(tile_count == expected_tile_count))
3162 1056 : CPASSERT(tile_index >= 1 .AND. tile_index <= PRODUCT(tile_count))
3163 264 : linear_tile = tile_index - 1
3164 264 : tile_coord(1) = MOD(linear_tile, tile_count(1))
3165 264 : linear_tile = linear_tile/tile_count(1)
3166 264 : tile_coord(2) = MOD(linear_tile, tile_count(2))
3167 264 : tile_coord(3) = linear_tile/tile_count(2)
3168 1056 : tile_lower = tile_coord*native_grid_adjoint_tile_edge
3169 1056 : tile_upper = MIN(tile_lower + native_grid_adjoint_tile_edge - 1, pw_grid%npts - 1)
3170 :
3171 264 : END SUBROUTINE native_grid_adjoint_tile_bounds
3172 :
3173 : ! **************************************************************************************************
3174 : !> \brief Apply the primitive-field interpolation transpose inside one disjoint PW tile.
3175 : !> \param density ...
3176 : !> \param grad ...
3177 : !> \param kin ...
3178 : !> \param pw_grid ...
3179 : !> \param stencil ...
3180 : !> \param density_value ...
3181 : !> \param grad_value ...
3182 : !> \param kin_value ...
3183 : !> \param nchannels number of spin channels accumulated by the adjoint
3184 : !> \param tile_lower zero-based lower grid index owned by this call
3185 : !> \param tile_upper zero-based upper grid index owned by this call
3186 : ! **************************************************************************************************
3187 458260 : SUBROUTINE add_native_grid_fields_adjoint_tile( &
3188 458260 : density, grad, kin, pw_grid, stencil, density_value, grad_value, kin_value, nchannels, &
3189 : tile_lower, tile_upper)
3190 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: density
3191 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT) :: grad
3192 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: kin
3193 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
3194 : TYPE(native_grid_interpolation_stencil_type), &
3195 : INTENT(IN) :: stencil
3196 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: density_value
3197 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: grad_value
3198 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: kin_value
3199 : INTEGER, INTENT(IN) :: nchannels
3200 : INTEGER, DIMENSION(3), INTENT(IN) :: tile_lower, tile_upper
3201 :
3202 : INTEGER :: idir, inode_x, inode_y, inode_z, ipt, &
3203 : ispin
3204 : INTEGER, DIMENSION(3) :: relative_index
3205 : REAL(KIND=dp) :: coefficient
3206 :
3207 458260 : CPASSERT(ASSOCIATED(pw_grid))
3208 1833040 : CPASSERT(SIZE(density, 1) == PRODUCT(pw_grid%npts))
3209 458260 : CPASSERT(SIZE(density, 2) == nchannels)
3210 1833040 : CPASSERT(SIZE(grad, 1) == PRODUCT(pw_grid%npts))
3211 458260 : CPASSERT(SIZE(grad, 2) == 3)
3212 458260 : CPASSERT(SIZE(grad, 3) == nchannels)
3213 1833040 : CPASSERT(SIZE(kin, 1) == PRODUCT(pw_grid%npts))
3214 458260 : CPASSERT(SIZE(kin, 2) == nchannels)
3215 458260 : CPASSERT(SIZE(density_value) == 2)
3216 1374780 : CPASSERT(ALL(SHAPE(grad_value) == [3, 2]))
3217 458260 : CPASSERT(SIZE(kin_value) == 2)
3218 458260 : CPASSERT(nchannels >= 1 .AND. nchannels <= 2)
3219 1833040 : CPASSERT(ALL(tile_lower >= 0))
3220 1833040 : CPASSERT(ALL(tile_upper >= tile_lower))
3221 1833040 : CPASSERT(ALL(tile_upper < pw_grid%npts))
3222 458260 : IF (.NOT. stencil%active) RETURN
3223 5957380 : DO inode_z = 1, native_grid_interp_npts
3224 5499120 : IF (.NOT. stencil%valid(inode_z, 3)) CYCLE
3225 5499120 : relative_index(3) = stencil%relative_index(inode_z, 3)
3226 5499120 : IF (relative_index(3) < tile_lower(3) .OR. relative_index(3) > tile_upper(3)) CYCLE
3227 71946820 : DO inode_y = 1, native_grid_interp_npts
3228 65989440 : IF (.NOT. stencil%valid(inode_y, 2)) CYCLE
3229 65989440 : relative_index(2) = stencil%relative_index(inode_y, 2)
3230 65989440 : IF (relative_index(2) < tile_lower(2) .OR. relative_index(2) > tile_upper(2)) CYCLE
3231 863361840 : DO inode_x = 1, native_grid_interp_npts
3232 791873280 : IF (.NOT. stencil%valid(inode_x, 1)) CYCLE
3233 791873280 : relative_index(1) = stencil%relative_index(inode_x, 1)
3234 791873280 : IF (relative_index(1) < tile_lower(1) .OR. relative_index(1) > tile_upper(1)) CYCLE
3235 : ipt = 1 + relative_index(1) + pw_grid%npts(1)*( &
3236 791873280 : relative_index(2) + pw_grid%npts(2)*relative_index(3))
3237 : coefficient = stencil%weight(inode_x, 1)* &
3238 : stencil%weight(inode_y, 2)* &
3239 791873280 : stencil%weight(inode_z, 3)
3240 1831176000 : DO ispin = 1, nchannels
3241 973313280 : density(ipt, ispin) = density(ipt, ispin) + coefficient*density_value(ispin)
3242 3893253120 : DO idir = 1, 3
3243 : grad(ipt, idir, ispin) = grad(ipt, idir, ispin) + &
3244 3893253120 : coefficient*grad_value(idir, ispin)
3245 : END DO
3246 1765186560 : kin(ipt, ispin) = kin(ipt, ispin) + coefficient*kin_value(ispin)
3247 : END DO
3248 : END DO
3249 : END DO
3250 : END DO
3251 :
3252 : END SUBROUTINE add_native_grid_fields_adjoint_tile
3253 :
3254 : ! **************************************************************************************************
3255 : !> \brief Interpolate a replicated native-grid field at a Cartesian point.
3256 : !> \param values ...
3257 : !> \param pw_grid ...
3258 : !> \param cell ...
3259 : !> \param point ...
3260 : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
3261 : !> \return ...
3262 : ! **************************************************************************************************
3263 375120 : FUNCTION interpolate_native_grid(values, pw_grid, cell, point, wrap_auxiliary_cell) RESULT(value)
3264 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: values
3265 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
3266 : TYPE(cell_type), INTENT(IN), POINTER :: cell
3267 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: point
3268 : LOGICAL, INTENT(IN), OPTIONAL :: wrap_auxiliary_cell
3269 : REAL(KIND=dp) :: value
3270 :
3271 : INTEGER :: corner_x, corner_y, corner_z, idir
3272 : INTEGER, DIMENSION(3) :: base, index, relative_index
3273 : LOGICAL :: wrap_grid
3274 : REAL(KIND=dp) :: coefficient
3275 : REAL(KIND=dp), DIMENSION(3) :: fraction, relative
3276 : REAL(KIND=dp), &
3277 : DIMENSION(native_grid_interp_npts, 3) :: weights
3278 :
3279 375120 : CPASSERT(ASSOCIATED(pw_grid))
3280 375120 : CPASSERT(ASSOCIATED(cell))
3281 1500480 : DO idir = 1, 3
3282 1500480 : CPASSERT(SIZE(values, idir) == pw_grid%npts(idir))
3283 : END DO
3284 :
3285 1365480 : wrap_grid = ANY(cell%perd == 0)
3286 375120 : IF (PRESENT(wrap_auxiliary_cell)) wrap_grid = wrap_auxiliary_cell
3287 4876560 : relative = MATMUL(pw_grid%dh_inv, point)
3288 1500480 : DO idir = 1, 3
3289 1125360 : IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
3290 1125360 : relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
3291 0 : ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
3292 : relative(idir) >= REAL(pw_grid%npts(idir) - &
3293 : native_grid_interp_offset_min, KIND=dp)) THEN
3294 375120 : value = 0.0_dp
3295 : RETURN
3296 : END IF
3297 1125360 : base(idir) = FLOOR(relative(idir))
3298 1125360 : FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
3299 1500480 : CALL native_grid_lagrange_weights(FRACTION(idir), weights(:, idir))
3300 : END DO
3301 :
3302 : value = 0.0_dp
3303 4876560 : DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
3304 58893840 : DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
3305 706726080 : DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
3306 2592829440 : relative_index = base + [corner_x, corner_y, corner_z]
3307 : coefficient = weights(corner_x - native_grid_interp_offset_min + 1, 1)* &
3308 : weights(corner_y - native_grid_interp_offset_min + 1, 2)* &
3309 648207360 : weights(corner_z - native_grid_interp_offset_min + 1, 3)
3310 2592829440 : DO idir = 1, 3
3311 2592829440 : IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
3312 1944622080 : relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
3313 0 : ELSE IF (relative_index(idir) < 0 .OR. &
3314 : relative_index(idir) >= pw_grid%npts(idir)) THEN
3315 0 : coefficient = 0.0_dp
3316 : END IF
3317 : END DO
3318 648207360 : IF (coefficient == 0.0_dp) CYCLE
3319 2248863840 : index = LBOUND(values) + relative_index
3320 702224640 : value = value + coefficient*values(INDEX(1), INDEX(2), INDEX(3))
3321 : END DO
3322 : END DO
3323 : END DO
3324 :
3325 : END FUNCTION interpolate_native_grid
3326 :
3327 : ! **************************************************************************************************
3328 : !> \brief Return the Cartesian gradient of native-grid interpolation at one point.
3329 : !> \param values ...
3330 : !> \param pw_grid ...
3331 : !> \param cell ...
3332 : !> \param point ...
3333 : !> \param wrap_auxiliary_cell wrap all auxiliary-grid directions
3334 : !> \return ...
3335 : ! **************************************************************************************************
3336 625200 : FUNCTION interpolate_native_grid_gradient(values, pw_grid, cell, point, &
3337 625200 : wrap_auxiliary_cell) RESULT(gradient)
3338 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: values
3339 : TYPE(pw_grid_type), INTENT(IN), POINTER :: pw_grid
3340 : TYPE(cell_type), INTENT(IN), POINTER :: cell
3341 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: point
3342 : LOGICAL, INTENT(IN), OPTIONAL :: wrap_auxiliary_cell
3343 : REAL(KIND=dp), DIMENSION(3) :: gradient
3344 :
3345 : INTEGER :: corner_x, corner_y, corner_z, idir, jdir
3346 : INTEGER, DIMENSION(3) :: base, corner_index, index, relative_index
3347 : LOGICAL :: wrap_grid
3348 : REAL(KIND=dp) :: coefficient
3349 : REAL(KIND=dp), DIMENSION(3) :: fraction, gradient_relative, relative
3350 : REAL(KIND=dp), &
3351 : DIMENSION(native_grid_interp_npts, 3) :: derivative_weights, weights
3352 :
3353 625200 : CPASSERT(ASSOCIATED(pw_grid))
3354 625200 : CPASSERT(ASSOCIATED(cell))
3355 2500800 : DO idir = 1, 3
3356 2500800 : CPASSERT(SIZE(values, idir) == pw_grid%npts(idir))
3357 : END DO
3358 :
3359 2275800 : wrap_grid = ANY(cell%perd == 0)
3360 625200 : IF (PRESENT(wrap_auxiliary_cell)) wrap_grid = wrap_auxiliary_cell
3361 8127600 : relative = MATMUL(pw_grid%dh_inv, point)
3362 2500800 : DO idir = 1, 3
3363 1875600 : IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
3364 1875600 : relative(idir) = MODULO(relative(idir), REAL(pw_grid%npts(idir), KIND=dp))
3365 0 : ELSE IF (relative(idir) <= -REAL(native_grid_interp_offset_max, dp) .OR. &
3366 : relative(idir) >= REAL(pw_grid%npts(idir) - &
3367 : native_grid_interp_offset_min, KIND=dp)) THEN
3368 0 : gradient = 0.0_dp
3369 0 : RETURN
3370 : END IF
3371 1875600 : base(idir) = FLOOR(relative(idir))
3372 1875600 : FRACTION(idir) = relative(idir) - REAL(base(idir), KIND=dp)
3373 : CALL native_grid_lagrange_weights( &
3374 2500800 : FRACTION(idir), weights(:, idir), derivative_weights(:, idir))
3375 : END DO
3376 :
3377 625200 : gradient_relative = 0.0_dp
3378 8127600 : DO corner_z = native_grid_interp_offset_min, native_grid_interp_offset_max
3379 98156400 : DO corner_y = native_grid_interp_offset_min, native_grid_interp_offset_max
3380 1177876800 : DO corner_x = native_grid_interp_offset_min, native_grid_interp_offset_max
3381 4321382400 : relative_index = base + [corner_x, corner_y, corner_z]
3382 : corner_index = [corner_x, corner_y, corner_z] - &
3383 4321382400 : native_grid_interp_offset_min + 1
3384 4321382400 : DO idir = 1, 3
3385 4321382400 : IF (cell%perd(idir) == 1 .OR. wrap_grid) THEN
3386 3241036800 : relative_index(idir) = MODULO(relative_index(idir), pw_grid%npts(idir))
3387 0 : ELSE IF (relative_index(idir) < 0 .OR. &
3388 : relative_index(idir) >= pw_grid%npts(idir)) THEN
3389 : EXIT
3390 : END IF
3391 : END DO
3392 1080345600 : IF (idir <= 3) CYCLE
3393 4321382400 : index = LBOUND(values) + relative_index
3394 4411411200 : DO idir = 1, 3
3395 : coefficient = 1.0_dp
3396 12964147200 : DO jdir = 1, 3
3397 12964147200 : IF (jdir == idir) THEN
3398 : coefficient = coefficient*derivative_weights( &
3399 3241036800 : corner_index(jdir), jdir)
3400 : ELSE
3401 : coefficient = coefficient*weights( &
3402 6482073600 : corner_index(jdir), jdir)
3403 : END IF
3404 : END DO
3405 : gradient_relative(idir) = gradient_relative(idir) + &
3406 4321382400 : coefficient*values(INDEX(1), INDEX(2), INDEX(3))
3407 : END DO
3408 : END DO
3409 : END DO
3410 : END DO
3411 625200 : gradient = MATMUL(TRANSPOSE(pw_grid%dh_inv), gradient_relative)
3412 :
3413 : END FUNCTION interpolate_native_grid_gradient
3414 :
3415 : ! **************************************************************************************************
3416 : !> \brief Build the value and optional derivative weights for the native-grid interpolation.
3417 : !> \param fraction fractional coordinate between two grid points
3418 : !> \param weights interpolation weights
3419 : !> \param derivative_weights optional derivatives with respect to fraction
3420 : ! **************************************************************************************************
3421 3452100 : SUBROUTINE native_grid_lagrange_weights(fraction, weights, derivative_weights)
3422 : REAL(KIND=dp), INTENT(IN) :: fraction
3423 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: weights
3424 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: derivative_weights
3425 :
3426 : INTEGER :: inode, jnode, knode, npoints
3427 : REAL(KIND=dp) :: denominator, derivative, numerator
3428 6904200 : REAL(KIND=dp), DIMENSION(SIZE(weights)) :: nodes
3429 :
3430 3452100 : npoints = SIZE(weights)
3431 3452100 : IF (PRESENT(derivative_weights)) THEN
3432 1875600 : CPASSERT(SIZE(derivative_weights) == npoints)
3433 : END IF
3434 44877300 : DO inode = 1, npoints
3435 44877300 : nodes(inode) = REAL(native_grid_interp_offset_min + inode - 1, dp)
3436 : END DO
3437 44877300 : DO inode = 1, npoints
3438 : denominator = 1.0_dp
3439 : numerator = 1.0_dp
3440 538527600 : DO jnode = 1, npoints
3441 497102400 : IF (jnode == inode) CYCLE
3442 455677200 : denominator = denominator*(nodes(inode) - nodes(jnode))
3443 538527600 : numerator = numerator*(fraction - nodes(jnode))
3444 : END DO
3445 41425200 : weights(inode) = numerator/denominator
3446 44877300 : IF (PRESENT(derivative_weights)) THEN
3447 : derivative = 0.0_dp
3448 292593600 : DO knode = 1, npoints
3449 270086400 : IF (knode == inode) CYCLE
3450 : numerator = 1.0_dp
3451 3218529600 : DO jnode = 1, npoints
3452 2970950400 : IF (jnode == inode .OR. jnode == knode) CYCLE
3453 3218529600 : numerator = numerator*(fraction - nodes(jnode))
3454 : END DO
3455 292593600 : derivative = derivative + numerator/denominator
3456 : END DO
3457 22507200 : derivative_weights(inode) = derivative
3458 : END IF
3459 : END DO
3460 :
3461 3452100 : END SUBROUTINE native_grid_lagrange_weights
3462 :
3463 : ! **************************************************************************************************
3464 : !> \brief Conservatively bound periodic images that can intersect a Cartesian support sphere.
3465 : !> \param cell current cell and periodicity
3466 : !> \param fractional target-minus-source displacement in lattice coordinates
3467 : !> \param cutoff current, density-dependent Cartesian support radius
3468 : !> \param image_shell original enclosing image shell
3469 : !> \param lower inclusive lower image indices
3470 : !> \param upper inclusive upper image indices (may be smaller than lower)
3471 : ! **************************************************************************************************
3472 543520 : SUBROUTINE atom_grid_image_bounds(cell, fractional, cutoff, image_shell, lower, upper)
3473 : TYPE(cell_type), INTENT(IN), POINTER :: cell
3474 : REAL(dp), INTENT(IN) :: fractional(3), cutoff
3475 : INTEGER, INTENT(IN) :: image_shell(3)
3476 : INTEGER, INTENT(OUT) :: lower(3), upper(3)
3477 :
3478 : INTEGER :: center, idir
3479 : REAL(dp) :: condition_bound, padding, radius
3480 :
3481 : ! |(H^-1 d)_i| <= cutoff ||(H^-1)_i|| also holds for triclinic cells.
3482 : ! Inflate the bounds for cancellation in fractional coordinates and the inverse cell.
3483 13588000 : condition_bound = MAX(1.0_dp, SUM(ABS(cell%hmat))*SUM(ABS(cell%h_inv)))
3484 543520 : lower = 0
3485 543520 : upper = 0
3486 2174080 : DO idir = 1, 3
3487 1630560 : IF (cell%perd(idir) == 0) CYCLE
3488 1330560 : center = NINT(fractional(idir))
3489 5322240 : radius = cutoff*SQRT(SUM(cell%h_inv(idir, :)**2))
3490 : padding = 128.0_dp*EPSILON(1.0_dp)*condition_bound* &
3491 5322240 : MAX(1.0_dp, MAXVAL(ABS(fractional)), radius)
3492 1330560 : lower(idir) = MAX(center - image_shell(idir), CEILING(fractional(idir) - radius - padding))
3493 2174080 : upper(idir) = MIN(center + image_shell(idir), FLOOR(fractional(idir) + radius + padding))
3494 : END DO
3495 543520 : END SUBROUTINE atom_grid_image_bounds
3496 :
3497 : ! **************************************************************************************************
3498 : !> \brief Express one radial node's first and second derivatives as linear combinations of the
3499 : !> local node values used by the C2-continuous quintic Hermite interpolant.
3500 : !> \param grid_atom radial source grid
3501 : !> \param descending whether radial nodes are stored in descending order
3502 : !> \param node logical index of the node whose derivatives are required
3503 : !> \param logical_start first logical index represented by the coefficient arrays
3504 : !> \param slope coefficients of the first derivative
3505 : !> \param curvature coefficients of the second derivative
3506 : ! **************************************************************************************************
3507 357470 : SUBROUTINE radial_node_derivative_coefficients( &
3508 : grid_atom, descending, node, logical_start, slope, curvature)
3509 : TYPE(grid_atom_type), POINTER :: grid_atom
3510 : LOGICAL, INTENT(IN) :: descending
3511 : INTEGER, INTENT(IN) :: node, logical_start
3512 : REAL(dp), DIMENSION(4), INTENT(OUT) :: slope, curvature
3513 :
3514 : INTEGER :: center, hi, lo, n
3515 : REAL(dp) :: h_hi, h_lo, x_center, x_hi, x_lo
3516 :
3517 357470 : n = grid_atom%nr
3518 357470 : slope = 0.0_dp
3519 357470 : curvature = 0.0_dp
3520 357470 : IF (node == 1) THEN
3521 : lo = 1
3522 : hi = 2
3523 357470 : ELSE IF (node == n) THEN
3524 0 : lo = n - 1
3525 0 : hi = n
3526 : ELSE
3527 357470 : lo = node - 1
3528 357470 : hi = node + 1
3529 : END IF
3530 357470 : x_lo = grid_atom%rad(MERGE(n + 1 - lo, lo, descending))
3531 357470 : x_hi = grid_atom%rad(MERGE(n + 1 - hi, hi, descending))
3532 357470 : slope(lo - logical_start + 1) = -1.0_dp/(x_hi - x_lo)
3533 357470 : slope(hi - logical_start + 1) = 1.0_dp/(x_hi - x_lo)
3534 :
3535 357470 : IF (n < 3) RETURN
3536 357470 : center = MIN(MAX(node, 2), n - 1)
3537 357470 : lo = center - 1
3538 357470 : hi = center + 1
3539 357470 : x_lo = grid_atom%rad(MERGE(n + 1 - lo, lo, descending))
3540 357470 : x_center = grid_atom%rad(MERGE(n + 1 - center, center, descending))
3541 357470 : x_hi = grid_atom%rad(MERGE(n + 1 - hi, hi, descending))
3542 357470 : h_lo = x_center - x_lo
3543 357470 : h_hi = x_hi - x_center
3544 357470 : curvature(lo - logical_start + 1) = 2.0_dp/(h_lo*(h_lo + h_hi))
3545 : curvature(center - logical_start + 1) = &
3546 357470 : -2.0_dp*(1.0_dp/h_lo + 1.0_dp/h_hi)/(h_lo + h_hi)
3547 357470 : curvature(hi - logical_start + 1) = 2.0_dp/(h_hi*(h_lo + h_hi))
3548 :
3549 : END SUBROUTINE radial_node_derivative_coefficients
3550 :
3551 : ! **************************************************************************************************
3552 : !> \brief Build mutually consistent value and Cartesian-derivative weights for interpolation from
3553 : !> a GAPW radial/Lebedev atom grid to one arbitrary local displacement.
3554 : !> \param grid_atom source atom grid
3555 : !> \param harmonics source spherical harmonics
3556 : !> \param displacement point minus source-image coordinate
3557 : !> \param cutoff compact support radius
3558 : !> \param radial_indices active radial nodes
3559 : !> \param radial_weights interpolation weights on the active radial nodes
3560 : !> \param radial_derivative_weights optional radial derivatives of the interpolation weights
3561 : !> \param nradial number of active radial nodes
3562 : !> \param angular_weights angular interpolation weights
3563 : !> \param angular_derivative_weights optional Cartesian derivatives of the angular weights
3564 : !> \param active whether the point lies inside the compact support
3565 : ! **************************************************************************************************
3566 178735 : SUBROUTINE atom_grid_interpolation_weights( &
3567 : grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
3568 178735 : radial_derivative_weights, nradial, angular_weights, angular_derivative_weights, active)
3569 : TYPE(grid_atom_type), POINTER :: grid_atom
3570 : TYPE(harmonics_atom_type), POINTER :: harmonics
3571 : REAL(dp), DIMENSION(3), INTENT(IN) :: displacement
3572 : REAL(dp), INTENT(IN) :: cutoff
3573 : INTEGER, DIMENSION(4), INTENT(OUT) :: radial_indices
3574 : REAL(dp), DIMENSION(4), INTENT(OUT) :: radial_weights
3575 : REAL(dp), DIMENSION(4), INTENT(OUT), OPTIONAL :: radial_derivative_weights
3576 : INTEGER, INTENT(OUT) :: nradial
3577 : REAL(dp), DIMENSION(:), INTENT(OUT) :: angular_weights
3578 : REAL(dp), DIMENSION(:, :), INTENT(OUT), OPTIONAL :: angular_derivative_weights
3579 : LOGICAL, INTENT(OUT) :: active
3580 :
3581 : INTEGER :: ia, ic, inode, iso, l, left, left_pos, &
3582 : logical_end, logical_start, lx, ly, &
3583 : lz, n, right_pos, shell_index
3584 : LOGICAL :: descending
3585 : REAL(dp) :: dh00, dh01, dh10, dh11, dh20, dh21, h00, &
3586 : h01, h10, h11, h20, h21, h_interval, &
3587 : monomial, radius, solid_derivative, t, &
3588 : x1, x2
3589 : REAL(dp), DIMENSION(3) :: direction
3590 357470 : REAL(dp), DIMENSION(harmonics%max_s_harm) :: angular_values
3591 : REAL(dp), DIMENSION(4) :: curvature_left, curvature_right, &
3592 : slope_left, slope_right
3593 0 : REAL(dp), DIMENSION(3, harmonics%max_s_harm) :: angular_value_derivatives
3594 :
3595 178735 : CPASSERT(ASSOCIATED(grid_atom))
3596 178735 : CPASSERT(ASSOCIATED(harmonics))
3597 178735 : CPASSERT(SIZE(angular_weights) == grid_atom%ng_sphere)
3598 178735 : IF (PRESENT(angular_derivative_weights)) THEN
3599 29955 : CPASSERT(SIZE(angular_derivative_weights, 1) == 3)
3600 29955 : CPASSERT(SIZE(angular_derivative_weights, 2) == grid_atom%ng_sphere)
3601 : END IF
3602 :
3603 178735 : radial_indices = 0
3604 178735 : radial_weights = 0.0_dp
3605 178735 : IF (PRESENT(radial_derivative_weights)) radial_derivative_weights = 0.0_dp
3606 7705401 : angular_weights = 0.0_dp
3607 5854519 : IF (PRESENT(angular_derivative_weights)) angular_derivative_weights = 0.0_dp
3608 178735 : nradial = 0
3609 178735 : active = .FALSE.
3610 178735 : n = grid_atom%nr
3611 178735 : descending = grid_atom%rad(1) > grid_atom%rad(n)
3612 714940 : radius = SQRT(SUM(displacement**2))
3613 178735 : IF (radius > cutoff .OR. &
3614 : radius > grid_atom%rad(MERGE(1, n, descending))) RETURN
3615 178735 : IF (radius <= 1.0E-12_dp) RETURN
3616 714940 : direction = displacement/radius
3617 :
3618 178735 : CPASSERT(n >= 2)
3619 178735 : left = n - 1
3620 357470 : IF (radius <= grid_atom%rad(MERGE(n, 1, descending))) THEN
3621 0 : left = 1
3622 : ELSE
3623 4338267 : DO inode = 1, n - 1
3624 4338267 : IF (radius <= grid_atom%rad(MERGE(n - inode, inode + 1, descending))) THEN
3625 178735 : left = inode
3626 178735 : EXIT
3627 : END IF
3628 : END DO
3629 : END IF
3630 :
3631 178735 : logical_start = MAX(1, left - 1)
3632 178735 : logical_end = MIN(n, left + 2)
3633 178735 : nradial = logical_end - logical_start + 1
3634 893675 : DO inode = 1, nradial
3635 : radial_indices(inode) = MERGE(n + 2 - logical_start - inode, &
3636 893675 : logical_start + inode - 1, descending)
3637 : END DO
3638 178735 : left_pos = left - logical_start + 1
3639 178735 : right_pos = left_pos + 1
3640 178735 : x1 = grid_atom%rad(radial_indices(left_pos))
3641 178735 : x2 = grid_atom%rad(radial_indices(right_pos))
3642 178735 : h_interval = x2 - x1
3643 178735 : t = (radius - x1)/h_interval
3644 :
3645 178735 : h00 = 1.0_dp - 10.0_dp*t**3 + 15.0_dp*t**4 - 6.0_dp*t**5
3646 178735 : h10 = t - 6.0_dp*t**3 + 8.0_dp*t**4 - 3.0_dp*t**5
3647 178735 : h20 = 0.5_dp*(t**2 - 3.0_dp*t**3 + 3.0_dp*t**4 - t**5)
3648 178735 : h01 = 10.0_dp*t**3 - 15.0_dp*t**4 + 6.0_dp*t**5
3649 178735 : h11 = -4.0_dp*t**3 + 7.0_dp*t**4 - 3.0_dp*t**5
3650 178735 : h21 = 0.5_dp*(t**3 - 2.0_dp*t**4 + t**5)
3651 :
3652 : CALL radial_node_derivative_coefficients( &
3653 178735 : grid_atom, descending, left, logical_start, slope_left, curvature_left)
3654 : CALL radial_node_derivative_coefficients( &
3655 178735 : grid_atom, descending, left + 1, logical_start, slope_right, curvature_right)
3656 178735 : radial_weights(left_pos) = radial_weights(left_pos) + h00
3657 178735 : radial_weights(right_pos) = radial_weights(right_pos) + h01
3658 : radial_weights(1:nradial) = radial_weights(1:nradial) + &
3659 : h_interval*(h10*slope_left(1:nradial) + &
3660 : h11*slope_right(1:nradial)) + &
3661 : h_interval**2*(h20*curvature_left(1:nradial) + &
3662 893675 : h21*curvature_right(1:nradial))
3663 178735 : IF (PRESENT(radial_derivative_weights)) THEN
3664 29955 : dh00 = -30.0_dp*t**2 + 60.0_dp*t**3 - 30.0_dp*t**4
3665 29955 : dh10 = 1.0_dp - 18.0_dp*t**2 + 32.0_dp*t**3 - 15.0_dp*t**4
3666 29955 : dh20 = 0.5_dp*(2.0_dp*t - 9.0_dp*t**2 + 12.0_dp*t**3 - 5.0_dp*t**4)
3667 29955 : dh01 = 30.0_dp*t**2 - 60.0_dp*t**3 + 30.0_dp*t**4
3668 29955 : dh11 = -12.0_dp*t**2 + 28.0_dp*t**3 - 15.0_dp*t**4
3669 29955 : dh21 = 0.5_dp*(3.0_dp*t**2 - 8.0_dp*t**3 + 5.0_dp*t**4)
3670 : radial_derivative_weights(left_pos) = &
3671 29955 : radial_derivative_weights(left_pos) + dh00/h_interval
3672 : radial_derivative_weights(right_pos) = &
3673 29955 : radial_derivative_weights(right_pos) + dh01/h_interval
3674 : radial_derivative_weights(1:nradial) = radial_derivative_weights(1:nradial) + &
3675 : dh10*slope_left(1:nradial) + &
3676 : dh11*slope_right(1:nradial) + &
3677 : h_interval*(dh20*curvature_left(1:nradial) + &
3678 149775 : dh21*curvature_right(1:nradial))
3679 : END IF
3680 :
3681 1066278 : angular_values = 0.0_dp
3682 860891 : IF (PRESENT(angular_derivative_weights)) angular_value_derivatives = 0.0_dp
3683 1066278 : DO iso = 1, harmonics%max_s_harm
3684 887543 : l = indso(1, iso)
3685 887543 : CALL y_lm(direction, angular_values(iso), l, indso(2, iso))
3686 887543 : IF (l == 0 .OR. .NOT. PRESENT(angular_derivative_weights)) CYCLE
3687 140584 : shell_index = iso - nsoset(l - 1)
3688 968806 : DO ic = 1, nco(l)
3689 828222 : lx = indco(1, ic + ncoset(l - 1))
3690 828222 : ly = indco(2, ic + ncoset(l - 1))
3691 828222 : lz = indco(3, ic + ncoset(l - 1))
3692 828222 : IF (lx > 0) THEN
3693 : monomial = REAL(lx, dp)*direction(1)**(lx - 1)* &
3694 424314 : direction(2)**ly*direction(3)**lz
3695 : angular_value_derivatives(1, iso) = angular_value_derivatives(1, iso) + &
3696 424314 : orbtramat(l)%slm(shell_index, ic)*monomial
3697 : END IF
3698 828222 : IF (ly > 0) THEN
3699 : monomial = direction(1)**lx*REAL(ly, dp)*direction(2)**(ly - 1)* &
3700 424314 : direction(3)**lz
3701 : angular_value_derivatives(2, iso) = angular_value_derivatives(2, iso) + &
3702 424314 : orbtramat(l)%slm(shell_index, ic)*monomial
3703 : END IF
3704 968806 : IF (lz > 0) THEN
3705 : monomial = direction(1)**lx*direction(2)**ly* &
3706 424314 : REAL(lz, dp)*direction(3)**(lz - 1)
3707 : angular_value_derivatives(3, iso) = angular_value_derivatives(3, iso) + &
3708 424314 : orbtramat(l)%slm(shell_index, ic)*monomial
3709 : END IF
3710 : END DO
3711 741071 : DO inode = 1, 3
3712 421752 : solid_derivative = angular_value_derivatives(inode, iso)
3713 : angular_value_derivatives(inode, iso) = (solid_derivative - &
3714 : REAL(l, dp)*angular_values(iso)* &
3715 1309295 : direction(inode))/radius
3716 : END DO
3717 : END DO
3718 :
3719 7705401 : DO ia = 1, grid_atom%ng_sphere
3720 : angular_weights(ia) = grid_atom%wa(ia)* &
3721 : DOT_PRODUCT(harmonics%slm(ia, 1:harmonics%max_s_harm), &
3722 45553092 : angular_values)
3723 7705401 : IF (PRESENT(angular_derivative_weights)) THEN
3724 5675784 : DO inode = 1, 3
3725 : angular_derivative_weights(inode, ia) = grid_atom%wa(ia)* &
3726 : DOT_PRODUCT(harmonics%slm(ia, 1:harmonics%max_s_harm), &
3727 28055838 : angular_value_derivatives(inode, :))
3728 : END DO
3729 : END IF
3730 : END DO
3731 178735 : active = .TRUE.
3732 :
3733 : END SUBROUTINE atom_grid_interpolation_weights
3734 :
3735 : ! **************************************************************************************************
3736 : !> \brief Interpolate hard-minus-soft primitive fields and their spatial derivatives from one
3737 : !> GAPW atom grid.
3738 : !> \param grid_atom radial and angular source grid
3739 : !> \param harmonics spherical-harmonic representation of the source grid
3740 : !> \param displacement target point relative to the source-atom image
3741 : !> \param cutoff compact support radius of the source fields
3742 : !> \param nspins number of spin channels
3743 : !> \param rho_h hard one-center density values
3744 : !> \param rho_s soft one-center density values
3745 : !> \param drho_h hard one-center density-gradient values
3746 : !> \param drho_s soft one-center density-gradient values
3747 : !> \param tau_h hard one-center kinetic-energy-density values
3748 : !> \param tau_s soft one-center kinetic-energy-density values
3749 : !> \param density interpolated hard-minus-soft density
3750 : !> \param gradient interpolated hard-minus-soft density gradient
3751 : !> \param kin interpolated hard-minus-soft kinetic-energy density
3752 : !> \param density_spatial Cartesian derivatives of density
3753 : !> \param gradient_spatial Cartesian derivatives of the density gradient
3754 : !> \param kin_spatial Cartesian derivatives of the kinetic-energy density
3755 : !> \param calculate_spatial evaluate spatial derivatives (default true), otherwise return zeros
3756 : ! **************************************************************************************************
3757 104345 : SUBROUTINE interpolate_gapw_atom_grid_fields( &
3758 208690 : grid_atom, harmonics, displacement, cutoff, nspins, rho_h, rho_s, drho_h, drho_s, &
3759 104345 : tau_h, tau_s, density, gradient, kin, density_spatial, gradient_spatial, kin_spatial, calculate_spatial)
3760 : TYPE(grid_atom_type), POINTER :: grid_atom
3761 : TYPE(harmonics_atom_type), POINTER :: harmonics
3762 : REAL(dp), DIMENSION(3), INTENT(IN) :: displacement
3763 : REAL(dp), INTENT(IN) :: cutoff
3764 : INTEGER, INTENT(IN) :: nspins
3765 : REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: rho_h, rho_s
3766 : REAL(dp), DIMENSION(:, :, :, :), INTENT(IN) :: drho_h, drho_s
3767 : REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: tau_h, tau_s
3768 : REAL(dp), DIMENSION(2), INTENT(OUT) :: density
3769 : REAL(dp), DIMENSION(3, 2), INTENT(OUT) :: gradient
3770 : REAL(dp), DIMENSION(2), INTENT(OUT) :: kin
3771 : REAL(dp), DIMENSION(3, 2), INTENT(OUT) :: density_spatial
3772 : REAL(dp), DIMENSION(3, 3, 2), INTENT(OUT) :: gradient_spatial
3773 : REAL(dp), DIMENSION(3, 2), INTENT(OUT) :: kin_spatial
3774 : LOGICAL, INTENT(IN), OPTIONAL :: calculate_spatial
3775 :
3776 : INTEGER :: ia, idir, inode, ir, ispin, jdir, nradial
3777 : INTEGER, DIMENSION(4) :: radial_indices
3778 : LOGICAL :: active, need_spatial
3779 : REAL(dp) :: derivative_weight, weight
3780 208690 : REAL(dp), DIMENSION(grid_atom%ng_sphere) :: angular_weights
3781 : REAL(dp), DIMENSION(4) :: radial_derivative_weights, radial_weights
3782 208690 : REAL(dp), DIMENSION(3, grid_atom%ng_sphere) :: angular_derivative_weights
3783 :
3784 104345 : density = 0.0_dp
3785 104345 : gradient = 0.0_dp
3786 104345 : kin = 0.0_dp
3787 104345 : density_spatial = 0.0_dp
3788 104345 : gradient_spatial = 0.0_dp
3789 104345 : kin_spatial = 0.0_dp
3790 104345 : need_spatial = .TRUE.
3791 104345 : IF (PRESENT(calculate_spatial)) need_spatial = calculate_spatial
3792 74390 : IF (need_spatial) THEN
3793 : CALL atom_grid_interpolation_weights( &
3794 : grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
3795 29955 : radial_derivative_weights, nradial, angular_weights, angular_derivative_weights, active)
3796 : ELSE
3797 : CALL atom_grid_interpolation_weights( &
3798 : grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
3799 74390 : nradial=nradial, angular_weights=angular_weights, active=active)
3800 : END IF
3801 104345 : IF (active) THEN
3802 521725 : DO inode = 1, nradial
3803 417380 : ir = radial_indices(inode)
3804 18412949 : DO ia = 1, grid_atom%ng_sphere
3805 17891224 : weight = radial_weights(inode)*angular_weights(ia)
3806 36199828 : DO ispin = 1, nspins
3807 : density(ispin) = density(ispin) + &
3808 17891224 : weight*(rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin))
3809 : kin(ispin) = kin(ispin) + &
3810 17891224 : weight*(tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin))
3811 89456120 : DO idir = 1, 3
3812 : gradient(idir, ispin) = gradient(idir, ispin) + &
3813 : weight*(drho_h(idir, ia, ir, ispin) - &
3814 53673672 : drho_s(idir, ia, ir, ispin))
3815 53673672 : IF (.NOT. need_spatial) CYCLE
3816 : derivative_weight = radial_derivative_weights(inode)* &
3817 : displacement(idir)/SQRT(SUM(displacement**2))* &
3818 : angular_weights(ia) + radial_weights(inode)* &
3819 68109408 : angular_derivative_weights(idir, ia)
3820 : density_spatial(idir, ispin) = density_spatial(idir, ispin) + &
3821 17027352 : derivative_weight*(rho_h(ia, ir, ispin) - rho_s(ia, ir, ispin))
3822 : kin_spatial(idir, ispin) = kin_spatial(idir, ispin) + &
3823 17027352 : derivative_weight*(tau_h(ia, ir, ispin) - tau_s(ia, ir, ispin))
3824 86000632 : DO jdir = 1, 3
3825 : gradient_spatial(jdir, idir, ispin) = &
3826 : gradient_spatial(jdir, idir, ispin) + derivative_weight*( &
3827 104755728 : drho_h(jdir, ia, ir, ispin) - drho_s(jdir, ia, ir, ispin))
3828 : END DO
3829 : END DO
3830 : END DO
3831 : END DO
3832 : END DO
3833 : END IF
3834 104345 : END SUBROUTINE interpolate_gapw_atom_grid_fields
3835 :
3836 : ! **************************************************************************************************
3837 : !> \brief Apply the exact transpose of interpolate_gapw_atom_grid_fields to one-center potentials.
3838 : !> \param grid_atom radial and angular source grid
3839 : !> \param harmonics spherical-harmonic representation of the source grid
3840 : !> \param displacement target point relative to the source-atom image
3841 : !> \param cutoff compact support radius of the source fields
3842 : !> \param nspins number of spin channels
3843 : !> \param density_adjoint model derivative with respect to density
3844 : !> \param gradient_adjoint model derivative with respect to the density gradient
3845 : !> \param kin_adjoint model derivative with respect to kinetic-energy density
3846 : !> \param vxc_h accumulated hard one-center density potential
3847 : !> \param vxc_s accumulated soft one-center density potential
3848 : !> \param vxg_h accumulated hard one-center density-gradient potential
3849 : !> \param vxg_s accumulated soft one-center density-gradient potential
3850 : !> \param vtau_h accumulated hard one-center kinetic-energy-density potential
3851 : !> \param vtau_s accumulated soft one-center kinetic-energy-density potential
3852 : ! **************************************************************************************************
3853 74390 : SUBROUTINE add_gapw_atom_grid_interpolation_adjoint( &
3854 : grid_atom, harmonics, displacement, cutoff, nspins, density_adjoint, gradient_adjoint, &
3855 74390 : kin_adjoint, vxc_h, vxc_s, vxg_h, vxg_s, vtau_h, vtau_s)
3856 : TYPE(grid_atom_type), POINTER :: grid_atom
3857 : TYPE(harmonics_atom_type), POINTER :: harmonics
3858 : REAL(dp), DIMENSION(3), INTENT(IN) :: displacement
3859 : REAL(dp), INTENT(IN) :: cutoff
3860 : INTEGER, INTENT(IN) :: nspins
3861 : REAL(dp), DIMENSION(2), INTENT(IN) :: density_adjoint
3862 : REAL(dp), DIMENSION(3, 2), INTENT(IN) :: gradient_adjoint
3863 : REAL(dp), DIMENSION(2), INTENT(IN) :: kin_adjoint
3864 : REAL(dp), DIMENSION(:, :, :), INTENT(INOUT) :: vxc_h, vxc_s
3865 : REAL(dp), DIMENSION(:, :, :, :), INTENT(INOUT) :: vxg_h, vxg_s
3866 : REAL(dp), DIMENSION(:, :, :), INTENT(INOUT) :: vtau_h, vtau_s
3867 :
3868 : INTEGER :: ia, idir, inode, ir, ispin, nradial
3869 : INTEGER, DIMENSION(4) :: radial_indices
3870 : LOGICAL :: active
3871 : REAL(dp) :: value
3872 : REAL(dp), DIMENSION(4) :: radial_weights
3873 148780 : REAL(dp), DIMENSION(grid_atom%ng_sphere) :: angular_weights
3874 :
3875 : CALL atom_grid_interpolation_weights( &
3876 : grid_atom, harmonics, displacement, cutoff, radial_indices, radial_weights, &
3877 74390 : nradial=nradial, angular_weights=angular_weights, active=active)
3878 74390 : IF (active) THEN
3879 371950 : DO inode = 1, nradial
3880 297560 : ir = radial_indices(inode)
3881 12587390 : DO ia = 1, grid_atom%ng_sphere
3882 12215440 : value = radial_weights(inode)*angular_weights(ia)
3883 24728440 : DO ispin = 1, nspins
3884 : ! CP2K applies the hard-minus-soft sign when the two one-center
3885 : ! matrices are assembled, so both stored potentials carry the
3886 : ! same transpose-interpolation coefficient.
3887 12215440 : vxc_h(ia, ir, ispin) = vxc_h(ia, ir, ispin) + value*density_adjoint(ispin)
3888 12215440 : vxc_s(ia, ir, ispin) = vxc_s(ia, ir, ispin) + value*density_adjoint(ispin)
3889 12215440 : vtau_h(ia, ir, ispin) = vtau_h(ia, ir, ispin) + value*kin_adjoint(ispin)
3890 12215440 : vtau_s(ia, ir, ispin) = vtau_s(ia, ir, ispin) + value*kin_adjoint(ispin)
3891 61077200 : DO idir = 1, 3
3892 : vxg_h(idir, ia, ir, ispin) = vxg_h(idir, ia, ir, ispin) + &
3893 36646320 : value*gradient_adjoint(idir, ispin)
3894 : vxg_s(idir, ia, ir, ispin) = vxg_s(idir, ia, ir, ispin) + &
3895 48861760 : value*gradient_adjoint(idir, ispin)
3896 : END DO
3897 : END DO
3898 : END DO
3899 : END DO
3900 : END IF
3901 74390 : END SUBROUTINE add_gapw_atom_grid_interpolation_adjoint
3902 :
3903 : ! **************************************************************************************************
3904 : !> \brief ...
3905 : !> \param qs_env ...
3906 : !> \param exc1 the on-body ex energy contribution
3907 : !> \param gradient_atom_set ...
3908 : ! **************************************************************************************************
3909 10 : SUBROUTINE calculate_vxc_atom_epr(qs_env, exc1, gradient_atom_set)
3910 :
3911 : TYPE(qs_environment_type), POINTER :: qs_env
3912 : REAL(dp), INTENT(INOUT) :: exc1
3913 : TYPE(nablavks_atom_type), DIMENSION(:), POINTER :: gradient_atom_set
3914 :
3915 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom_epr'
3916 :
3917 : INTEGER :: bo(2), handle, ia, iat, iatom, idir, &
3918 : ikind, ir, ispin, myfun, na, natom, &
3919 : nr, nspins, num_pe
3920 : INTEGER, DIMENSION(2, 3) :: bounds
3921 10 : INTEGER, DIMENSION(:), POINTER :: atom_list
3922 : LOGICAL :: accint, donlcc, gradient_f, lsd, nlcc, &
3923 : paw_atom, tau_f
3924 : REAL(dp) :: agr, alpha, density_cut, exc_h, exc_s, &
3925 : gradient_cut, tau_cut
3926 : REAL(dp), DIMENSION(1, 1, 1) :: tau_d
3927 : REAL(dp), DIMENSION(1, 1, 1, 1) :: rho_d
3928 20 : REAL(dp), DIMENSION(:, :), POINTER :: rho_nlcc, weight_h, weight_s
3929 20 : REAL(dp), DIMENSION(:, :, :), POINTER :: rho_h, rho_s, tau_h, tau_s, vtau_h, &
3930 10 : vtau_s, vxc_h, vxc_s
3931 20 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s, vxg_h, vxg_s
3932 10 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3933 : TYPE(dft_control_type), POINTER :: dft_control
3934 : TYPE(grid_atom_type), POINTER :: grid_atom
3935 : TYPE(gto_basis_set_type), POINTER :: basis_1c
3936 : TYPE(harmonics_atom_type), POINTER :: harmonics
3937 : TYPE(mp_para_env_type), POINTER :: para_env
3938 10 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: my_kind_set
3939 10 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
3940 10 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
3941 10 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: my_rho_atom_set
3942 : TYPE(rho_atom_type), POINTER :: rho_atom
3943 : TYPE(section_vals_type), POINTER :: input, my_xc_section, xc_fun_section
3944 10 : TYPE(tau_basis_cache_type) :: tau_basis_cache
3945 : TYPE(xc_derivative_set_type) :: deriv_set
3946 : TYPE(xc_rho_cflags_type) :: needs
3947 : TYPE(xc_rho_set_type) :: rho_set_h, rho_set_s
3948 :
3949 : ! -------------------------------------------------------------------------
3950 :
3951 10 : CALL timeset(routineN, handle)
3952 :
3953 10 : NULLIFY (atom_list)
3954 10 : NULLIFY (my_kind_set)
3955 10 : NULLIFY (atomic_kind_set)
3956 10 : NULLIFY (grid_atom)
3957 10 : NULLIFY (harmonics)
3958 10 : NULLIFY (input)
3959 10 : NULLIFY (para_env)
3960 10 : NULLIFY (rho_atom)
3961 10 : NULLIFY (my_rho_atom_set)
3962 10 : NULLIFY (rho_nlcc)
3963 :
3964 : CALL get_qs_env(qs_env=qs_env, &
3965 : dft_control=dft_control, &
3966 : para_env=para_env, &
3967 : atomic_kind_set=atomic_kind_set, &
3968 : qs_kind_set=my_kind_set, &
3969 : input=input, &
3970 10 : rho_atom_set=my_rho_atom_set)
3971 :
3972 10 : nlcc = has_nlcc(my_kind_set)
3973 10 : accint = dft_control%qs_control%gapw_control%accurate_xcint
3974 :
3975 : my_xc_section => section_vals_get_subs_vals(input, &
3976 10 : "PROPERTIES%LINRES%EPR%PRINT%G_TENSOR%XC")
3977 10 : xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
3978 : CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
3979 10 : i_val=myfun)
3980 :
3981 10 : IF (myfun == xc_none) THEN
3982 0 : exc1 = 0.0_dp
3983 0 : my_rho_atom_set(:)%exc_h = 0.0_dp
3984 0 : my_rho_atom_set(:)%exc_s = 0.0_dp
3985 : ELSE
3986 : CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
3987 10 : r_val=density_cut)
3988 : CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
3989 10 : r_val=gradient_cut)
3990 : CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
3991 10 : r_val=tau_cut)
3992 :
3993 10 : lsd = dft_control%lsd
3994 10 : nspins = dft_control%nspins
3995 : needs = xc_functionals_get_needs(xc_fun_section, &
3996 : lsd=lsd, &
3997 10 : calc_potential=.TRUE.)
3998 :
3999 : ! whatever the xc, if epr_xc, drho_spin is needed
4000 10 : needs%drho_spin = .TRUE.
4001 :
4002 10 : gradient_f = (needs%drho .OR. needs%drho_spin)
4003 10 : tau_f = (needs%tau .OR. needs%tau_spin)
4004 :
4005 : ! Initialize energy contribution from the one center XC terms to zero
4006 10 : exc1 = 0.0_dp
4007 :
4008 : ! Nullify some pointers for work-arrays
4009 10 : NULLIFY (rho_h, drho_h, rho_s, drho_s, weight_h, weight_s)
4010 10 : NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
4011 10 : NULLIFY (tau_h, tau_s)
4012 10 : NULLIFY (vtau_h, vtau_s)
4013 :
4014 : ! Here starts the loop over all the atoms
4015 :
4016 30 : DO ikind = 1, SIZE(atomic_kind_set)
4017 20 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
4018 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
4019 20 : harmonics=harmonics, grid_atom=grid_atom)
4020 20 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
4021 :
4022 20 : IF (.NOT. paw_atom) CYCLE
4023 :
4024 20 : nr = grid_atom%nr
4025 20 : na = grid_atom%ng_sphere
4026 :
4027 : ! Prepare the structures needed to calculate and store the xc derivatives
4028 :
4029 : ! Array dimension: here anly one dimensional arrays are used,
4030 : ! i.e. only the first column of deriv_data is read.
4031 : ! The other to dimensions are set to size equal 1
4032 200 : bounds(1:2, 1:3) = 1
4033 20 : bounds(2, 1) = na
4034 20 : bounds(2, 2) = nr
4035 :
4036 : ! set integration weights
4037 20 : IF (accint) THEN
4038 0 : weight_h => grid_atom%weight
4039 0 : alpha = dft_control%qs_control%gapw_control%aw(ikind)
4040 0 : IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
4041 0 : IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
4042 : END IF
4043 0 : IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
4044 0 : ALLOCATE (grid_atom%gapw_weight_s(na, nr))
4045 0 : DO ir = 1, nr
4046 0 : agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
4047 0 : grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
4048 : END DO
4049 0 : grid_atom%gapw_weight_alpha = alpha
4050 : END IF
4051 0 : weight_s => grid_atom%gapw_weight_s
4052 : ELSE
4053 20 : weight_h => grid_atom%weight
4054 20 : weight_s => grid_atom%weight
4055 : END IF
4056 :
4057 : ! create a place where to put the derivatives
4058 20 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
4059 : ! create the place where to store the argument for the functionals
4060 : CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
4061 20 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
4062 : CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
4063 20 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
4064 :
4065 : ! allocate the required 3d arrays where to store rho and drho
4066 20 : CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
4067 20 : CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
4068 :
4069 20 : CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
4070 20 : CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
4071 20 : CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
4072 20 : CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
4073 : !
4074 : IF (gradient_f) THEN
4075 20 : CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
4076 20 : CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
4077 20 : CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
4078 20 : CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
4079 : END IF
4080 :
4081 20 : IF (tau_f) THEN
4082 0 : CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
4083 0 : CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
4084 0 : CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
4085 0 : CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
4086 0 : CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
4087 : END IF
4088 :
4089 : ! NLCC: prepare rho and drho of the core charge for this KIND
4090 20 : donlcc = .FALSE.
4091 20 : IF (nlcc) THEN
4092 0 : NULLIFY (rho_nlcc)
4093 0 : rho_nlcc => my_kind_set(ikind)%nlcc_pot
4094 0 : IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
4095 : END IF
4096 :
4097 : ! Distribute the atoms of this kind
4098 :
4099 20 : num_pe = para_env%num_pe
4100 20 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
4101 :
4102 35 : DO iat = bo(1), bo(2)
4103 15 : iatom = atom_list(iat)
4104 :
4105 15 : my_rho_atom_set(iatom)%exc_h = 0.0_dp
4106 15 : my_rho_atom_set(iatom)%exc_s = 0.0_dp
4107 :
4108 15 : rho_atom => my_rho_atom_set(iatom)
4109 76545 : rho_h = 0.0_dp
4110 76545 : rho_s = 0.0_dp
4111 : IF (gradient_f) THEN
4112 15 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
4113 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
4114 : rho_rad_s=r_s, drho_rad_h=dr_h, &
4115 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
4116 15 : rho_rad_s_d=r_s_d)
4117 376545 : drho_h = 0.0_dp
4118 376545 : drho_s = 0.0_dp
4119 : ELSE
4120 : NULLIFY (r_h, r_s)
4121 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
4122 : rho_d = 0.0_dp
4123 : END IF
4124 15 : IF (tau_f) THEN
4125 : !compute tau on the grid all at once
4126 0 : CALL calc_tau_atom(tau_h, tau_s, rho_atom, tau_basis_cache, nspins)
4127 : ELSE
4128 15 : tau_d = 0.0_dp
4129 : END IF
4130 :
4131 765 : DO ir = 1, nr
4132 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
4133 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
4134 750 : r_h_d, r_s_d, drho_h, drho_s)
4135 765 : IF (donlcc) THEN
4136 : CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
4137 0 : ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
4138 : END IF
4139 : END DO
4140 765 : DO ir = 1, nr
4141 765 : IF (tau_f) THEN
4142 0 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
4143 0 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
4144 : ELSE IF (gradient_f) THEN
4145 750 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
4146 750 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
4147 : ELSE
4148 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
4149 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
4150 : END IF
4151 : END DO
4152 :
4153 : !-------------------!
4154 : ! hard atom density !
4155 : !-------------------!
4156 15 : CALL xc_dset_zero_all(deriv_set)
4157 : CALL vxc_of_r_epr(xc_fun_section, rho_set_h, deriv_set, needs, weight_h, &
4158 15 : lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
4159 15 : rho_atom%exc_h = rho_atom%exc_h + exc_h
4160 :
4161 : !-------------------!
4162 : ! soft atom density !
4163 : !-------------------!
4164 15 : CALL xc_dset_zero_all(deriv_set)
4165 : CALL vxc_of_r_epr(xc_fun_section, rho_set_s, deriv_set, needs, weight_s, &
4166 15 : lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
4167 15 : rho_atom%exc_s = rho_atom%exc_s + exc_s
4168 :
4169 45 : DO ispin = 1, nspins
4170 135 : DO idir = 1, 3
4171 4620 : DO ir = 1, nr
4172 229590 : DO ia = 1, na
4173 : gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) = &
4174 : gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) &
4175 225000 : + vxg_h(idir, ia, ir, ispin)
4176 : gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) = &
4177 : gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) &
4178 229500 : + vxg_s(idir, ia, ir, ispin)
4179 : END DO ! ia
4180 : END DO ! ir
4181 : END DO ! idir
4182 : END DO ! ispin
4183 :
4184 : ! Add contributions to the exc energy
4185 :
4186 15 : exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
4187 :
4188 : ! Integration to get the matrix elements relative to the vxc_atom
4189 : ! here the products with the primitives is done: gaVxcgb
4190 : ! internal transformation to get the integral in cartesian Gaussians
4191 :
4192 15 : NULLIFY (int_hh, int_ss)
4193 15 : CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
4194 : IF (gradient_f) THEN
4195 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
4196 15 : grid_atom, basis_1c, harmonics, nspins)
4197 : ELSE
4198 : CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
4199 : grid_atom, basis_1c, harmonics, nspins)
4200 : END IF
4201 15 : IF (tau_f) THEN
4202 : CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
4203 0 : tau_basis_cache, nspins)
4204 : END IF
4205 35 : NULLIFY (r_h, r_s, dr_h, dr_s)
4206 : END DO ! iat
4207 :
4208 20 : IF (tau_f) CALL release_tau_basis_cache(tau_basis_cache)
4209 :
4210 : ! Release the xc structure used to store the xc derivatives
4211 20 : CALL xc_dset_release(deriv_set)
4212 20 : CALL xc_rho_set_release(rho_set_h)
4213 70 : CALL xc_rho_set_release(rho_set_s)
4214 : END DO ! ikind
4215 :
4216 10 : CALL para_env%sum(exc1)
4217 :
4218 10 : IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
4219 10 : IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
4220 10 : IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
4221 10 : IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
4222 :
4223 : IF (gradient_f) THEN
4224 10 : IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
4225 10 : IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
4226 10 : IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
4227 10 : IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
4228 : END IF
4229 :
4230 10 : IF (tau_f) THEN
4231 0 : IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
4232 0 : IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
4233 0 : IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
4234 0 : IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
4235 : END IF
4236 :
4237 : END IF !xc_none
4238 :
4239 10 : CALL timestop(handle)
4240 :
4241 380 : END SUBROUTINE calculate_vxc_atom_epr
4242 :
4243 : END MODULE qs_vxc_atom
|