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