(git:98357aa)
Loading...
Searching...
No Matches
qs_cdft_grid.F
Go to the documentation of this file.
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 Pointwise CDFT partition functions for nonuniform integration grids.
10! **************************************************************************************************
14 USE cell_types, ONLY: cell_type,&
15 pbc
24 USE kinds, ONLY: dp
33#include "./base/base_uses.f90"
34
35 IMPLICIT NONE
36
37 PRIVATE
38
39 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_cdft_grid'
40
42 INTEGER :: method = -1, natom = 0, ngroup = 0
43 INTEGER, ALLOCATABLE, DIMENSION(:) :: numexp, cavity_numexp
44 LOGICAL :: calculate_derivatives = .false., &
45 cavity_confine = .false.
46 LOGICAL, ALLOCATABLE, DIMENSION(:) :: constraint_atom
47 REAL(kind=dp) :: eps = 0.0_dp, eps_cavity = 0.0_dp
48 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: cutoffs, distances, cell_functions
49 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: atom_coords, aij, coefficients, &
50 alpha, amplitude, cavity_alpha, &
51 cavity_amplitude, displacement, &
52 datom_numerator, datom_sum, dcell_point, &
53 density_atom_derivative
54 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: pair_vectors, dcell_atom
55 TYPE(cell_type), POINTER :: cell => null()
57
58 PUBLIC :: cdft_point_context_create, &
62
63CONTAINS
64
65! **************************************************************************************************
66!> \brief Initialize reusable data for pointwise CDFT partition evaluation.
67!> \param qs_env Quickstep environment
68!> \param context pointwise partition context
69!> \param calculate_derivatives allocate scratch space for coordinate derivatives
70! **************************************************************************************************
71 SUBROUTINE cdft_point_context_create(qs_env, context, calculate_derivatives)
72 TYPE(qs_environment_type), POINTER :: qs_env
73 TYPE(cdft_point_context_type), INTENT(OUT) :: context
74 LOGICAL, INTENT(IN), OPTIONAL :: calculate_derivatives
75
76 INTEGER :: atom, iatom, igroup, ikind, jatom, natom
77 REAL(kind=dp) :: chi, ircov, jrcov, uij
78 REAL(kind=dp), DIMENSION(3) :: pair_vector
79 REAL(kind=dp), DIMENSION(:), POINTER :: radii, radii_list
80 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
81 TYPE(becke_constraint_type), POINTER :: becke_control
82 TYPE(cdft_control_type), POINTER :: cdft_control
83 TYPE(dft_control_type), POINTER :: dft_control
84 TYPE(hirshfeld_constraint_type), POINTER :: hirshfeld_control
85 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
86 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
87 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
88
89 NULLIFY (becke_control, cdft_control, dft_control, hirshfeld_control, &
90 hirshfeld_env, atomic_kind_set, particle_set, qs_kind_set, radii, radii_list)
91 CALL get_qs_env(qs_env, cell=context%cell, dft_control=dft_control, &
92 natom=natom, particle_set=particle_set, atomic_kind_set=atomic_kind_set, &
93 qs_kind_set=qs_kind_set)
94 cpassert(ASSOCIATED(context%cell))
95 cpassert(ASSOCIATED(dft_control))
96 cpassert(ASSOCIATED(particle_set))
97 cpassert(ASSOCIATED(atomic_kind_set))
98 cpassert(ASSOCIATED(qs_kind_set))
99 cdft_control => dft_control%qs_control%cdft_control
100 cpassert(ASSOCIATED(cdft_control))
101
102 context%method = cdft_control%type
103 context%natom = natom
104 context%ngroup = SIZE(cdft_control%group)
105 context%calculate_derivatives = .false.
106 IF (PRESENT(calculate_derivatives)) context%calculate_derivatives = calculate_derivatives
107 ALLOCATE (context%atom_coords(3, natom), &
108 context%coefficients(context%ngroup, natom), &
109 context%constraint_atom(natom), &
110 context%distances(natom), context%displacement(3, natom), &
111 context%cell_functions(natom))
112 context%coefficients = 0.0_dp
113 context%constraint_atom = .false.
114 DO atom = 1, natom
115 context%atom_coords(:, atom) = particle_set(atom)%r
116 END DO
117 DO igroup = 1, context%ngroup
118 DO iatom = 1, SIZE(cdft_control%group(igroup)%atoms)
119 atom = cdft_control%group(igroup)%atoms(iatom)
120 context%coefficients(igroup, atom) = cdft_control%group(igroup)%coeff(iatom)
121 context%constraint_atom(atom) = .true.
122 END DO
123 END DO
124
125 SELECT CASE (context%method)
127 becke_control => cdft_control%becke_control
128 cpassert(ASSOCIATED(becke_control))
129 ALLOCATE (context%cutoffs(natom), context%aij(natom, natom), &
130 context%pair_vectors(3, natom, natom))
131 IF (context%calculate_derivatives) THEN
132 ALLOCATE (context%dcell_point(3, natom), context%dcell_atom(3, natom, natom), &
133 context%datom_sum(3, natom), context%datom_numerator(3, natom))
134 END IF
135 IF (ASSOCIATED(becke_control%cutoffs)) THEN
136 context%cutoffs(:) = becke_control%cutoffs
137 ELSE
138 SELECT CASE (becke_control%cutoff_type)
140 context%cutoffs = becke_control%rglobal
142 cpassert(ASSOCIATED(becke_control%cutoffs_tmp))
143 cpassert(SIZE(becke_control%cutoffs_tmp) == SIZE(atomic_kind_set))
144 DO atom = 1, natom
145 CALL get_atomic_kind(particle_set(atom)%atomic_kind, kind_number=ikind)
146 context%cutoffs(atom) = becke_control%cutoffs_tmp(ikind)
147 END DO
148 CASE DEFAULT
149 cpabort("Unknown Becke cutoff type.")
150 END SELECT
151 END IF
152 context%aij = 0.0_dp
153 IF (becke_control%adjust) THEN
154 IF (ASSOCIATED(becke_control%aij)) THEN
155 context%aij(:, :) = becke_control%aij
156 ELSE
157 IF (ASSOCIATED(becke_control%radii)) THEN
158 radii => becke_control%radii
159 ELSE
160 radii => becke_control%radii_tmp
161 END IF
162 cpassert(ASSOCIATED(radii))
163 cpassert(SIZE(radii) == SIZE(atomic_kind_set))
164 DO iatom = 1, natom - 1
165 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
166 ircov = radii(ikind)
167 DO jatom = iatom + 1, natom
168 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=ikind)
169 jrcov = radii(ikind)
170 IF (ircov /= jrcov) THEN
171 chi = ircov/jrcov
172 uij = (chi - 1.0_dp)/(chi + 1.0_dp)
173 context%aij(iatom, jatom) = max(-0.5_dp, min(0.5_dp, &
174 uij/(uij**2 - 1.0_dp)))
175 context%aij(jatom, iatom) = -context%aij(iatom, jatom)
176 END IF
177 END DO
178 END DO
179 END IF
180 END IF
181 context%pair_vectors = 0.0_dp
182 DO iatom = 1, natom - 1
183 DO jatom = iatom + 1, natom
184 pair_vector = pbc(context%atom_coords(:, jatom), &
185 context%atom_coords(:, iatom), context%cell)
186 context%pair_vectors(:, iatom, jatom) = pair_vector
187 context%pair_vectors(:, jatom, iatom) = -pair_vector
188 END DO
189 END DO
190 context%cavity_confine = becke_control%cavity_confine
191 context%eps_cavity = becke_control%eps_cavity
192 IF (context%cavity_confine) THEN
193 hirshfeld_env => becke_control%cavity_env
194 cpassert(ASSOCIATED(hirshfeld_env))
195 IF (.NOT. ASSOCIATED(hirshfeld_env%kind_shape_fn)) THEN
196 IF (ASSOCIATED(becke_control%radii)) THEN
197 radii => becke_control%radii
198 ELSE IF (ASSOCIATED(becke_control%radii_tmp)) THEN
199 radii => becke_control%radii_tmp
200 END IF
201 IF (ASSOCIATED(radii)) THEN
202 ALLOCATE (radii_list(SIZE(radii)))
203 DO ikind = 1, SIZE(radii)
204 IF (hirshfeld_env%use_bohr) THEN
205 radii_list(ikind) = radii(ikind)
206 ELSE
207 radii_list(ikind) = cp_unit_from_cp2k(radii(ikind), "angstrom")
208 END IF
209 END DO
210 END IF
211 CALL create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, &
212 radius=becke_control%rcavity, radii_list=radii_list)
213 IF (ASSOCIATED(radii_list)) DEALLOCATE (radii_list)
214 END IF
215 CALL store_shape_functions(hirshfeld_env, particle_set, context%cavity_numexp, &
216 context%cavity_alpha, context%cavity_amplitude, &
217 include_charge=.false.)
218 END IF
220 hirshfeld_control => cdft_control%hirshfeld_control
221 cpassert(ASSOCIATED(hirshfeld_control))
222 hirshfeld_env => hirshfeld_control%hirshfeld_env
223 cpassert(ASSOCIATED(hirshfeld_env))
224 IF (.NOT. ASSOCIATED(hirshfeld_env%kind_shape_fn) .OR. &
225 .NOT. ASSOCIATED(hirshfeld_env%charges)) THEN
226 CALL hirshfeld_constraint_init(qs_env)
227 END IF
228 context%eps = hirshfeld_control%eps_cutoff
229 CALL store_shape_functions(hirshfeld_env, particle_set, context%numexp, &
230 context%alpha, context%amplitude, include_charge=.true.)
231 IF (context%calculate_derivatives) THEN
232 ALLOCATE (context%density_atom_derivative(3, natom))
233 END IF
234 CASE DEFAULT
235 cpabort("Unknown CDFT partition type.")
236 END SELECT
237
238 CONTAINS
239
240! **************************************************************************************************
241!> \brief ...
242!> \param environment ...
243!> \param particles ...
244!> \param numexp ...
245!> \param alpha ...
246!> \param amplitude ...
247!> \param include_charge ...
248! **************************************************************************************************
249 SUBROUTINE store_shape_functions(environment, particles, numexp, alpha, amplitude, &
250 include_charge)
251 TYPE(hirshfeld_type), POINTER :: environment
252 TYPE(particle_type), DIMENSION(:), POINTER :: particles
253 INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(OUT) :: numexp
254 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
255 INTENT(OUT) :: alpha, amplitude
256 LOGICAL, INTENT(IN) :: include_charge
257
258 INTEGER :: atom, iexp, ikind, maxexp
259 REAL(kind=dp) :: charge
260
261 ALLOCATE (numexp(natom))
262 numexp = 0
263 maxexp = 0
264 DO atom = 1, natom
265 CALL get_atomic_kind(particles(atom)%atomic_kind, kind_number=ikind)
266 numexp(atom) = environment%kind_shape_fn(ikind)%numexp
267 maxexp = max(maxexp, numexp(atom))
268 END DO
269 ALLOCATE (alpha(maxexp, natom), amplitude(maxexp, natom))
270 alpha = 0.0_dp
271 amplitude = 0.0_dp
272 DO atom = 1, natom
273 CALL get_atomic_kind(particles(atom)%atomic_kind, kind_number=ikind)
274 charge = 1.0_dp
275 IF (include_charge) charge = environment%charges(atom)
276 DO iexp = 1, numexp(atom)
277 alpha(iexp, atom) = environment%kind_shape_fn(ikind)%zet(iexp)
278 amplitude(iexp, atom) = charge*environment%kind_shape_fn(ikind)%coef(iexp)
279 END DO
280 END DO
281 END SUBROUTINE store_shape_functions
282
283 END SUBROUTINE cdft_point_context_create
284
285! **************************************************************************************************
286!> \brief Release a pointwise CDFT partition context.
287!> \param context pointwise partition context
288! **************************************************************************************************
289 SUBROUTINE cdft_point_context_release(context)
290 TYPE(cdft_point_context_type), INTENT(INOUT) :: context
291
292 IF (ALLOCATED(context%numexp)) DEALLOCATE (context%numexp)
293 IF (ALLOCATED(context%cavity_numexp)) DEALLOCATE (context%cavity_numexp)
294 IF (ALLOCATED(context%constraint_atom)) DEALLOCATE (context%constraint_atom)
295 IF (ALLOCATED(context%cutoffs)) DEALLOCATE (context%cutoffs)
296 IF (ALLOCATED(context%distances)) DEALLOCATE (context%distances)
297 IF (ALLOCATED(context%cell_functions)) DEALLOCATE (context%cell_functions)
298 IF (ALLOCATED(context%datom_sum)) DEALLOCATE (context%datom_sum)
299 IF (ALLOCATED(context%atom_coords)) DEALLOCATE (context%atom_coords)
300 IF (ALLOCATED(context%aij)) DEALLOCATE (context%aij)
301 IF (ALLOCATED(context%coefficients)) DEALLOCATE (context%coefficients)
302 IF (ALLOCATED(context%alpha)) DEALLOCATE (context%alpha)
303 IF (ALLOCATED(context%amplitude)) DEALLOCATE (context%amplitude)
304 IF (ALLOCATED(context%cavity_alpha)) DEALLOCATE (context%cavity_alpha)
305 IF (ALLOCATED(context%cavity_amplitude)) DEALLOCATE (context%cavity_amplitude)
306 IF (ALLOCATED(context%displacement)) DEALLOCATE (context%displacement)
307 IF (ALLOCATED(context%datom_numerator)) DEALLOCATE (context%datom_numerator)
308 IF (ALLOCATED(context%dcell_point)) DEALLOCATE (context%dcell_point)
309 IF (ALLOCATED(context%density_atom_derivative)) DEALLOCATE (context%density_atom_derivative)
310 IF (ALLOCATED(context%pair_vectors)) DEALLOCATE (context%pair_vectors)
311 IF (ALLOCATED(context%dcell_atom)) DEALLOCATE (context%dcell_atom)
312 NULLIFY (context%cell)
313 context%method = -1
314 context%natom = 0
315 context%ngroup = 0
316 context%calculate_derivatives = .false.
317 END SUBROUTINE cdft_point_context_release
318
319! **************************************************************************************************
320!> \brief Evaluate CDFT weights and coordinate derivatives at one point.
321!> \param context pointwise partition context
322!> \param point Cartesian point
323!> \param weights group weights
324!> \param point_derivative derivatives with respect to the Cartesian point
325!> \param atom_derivative derivatives with respect to atom positions at fixed point
326!> \param atomic_weights optional individual atomic partition weights
327! **************************************************************************************************
328 SUBROUTINE cdft_point_weights(context, point, weights, point_derivative, atom_derivative, &
329 atomic_weights)
330 TYPE(cdft_point_context_type), INTENT(INOUT) :: context
331 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: point
332 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: weights
333 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: point_derivative
334 REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: atom_derivative
335 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: atomic_weights
336
337 cpassert(SIZE(weights) == context%ngroup)
338 cpassert(SIZE(point_derivative, 1) == 3)
339 cpassert(SIZE(point_derivative, 2) == context%ngroup)
340 cpassert(SIZE(atom_derivative, 1) == 3)
341 cpassert(SIZE(atom_derivative, 2) == context%natom)
342 cpassert(SIZE(atom_derivative, 3) == context%ngroup)
343 IF (PRESENT(atomic_weights)) THEN
344 cpassert(SIZE(atomic_weights) == context%natom)
345 END IF
346 SELECT CASE (context%method)
348 CALL becke_point_weights(context, point, weights, point_derivative, atom_derivative, &
349 atomic_weights, context%calculate_derivatives)
351 CALL hirshfeld_point_weights(context, point, weights, point_derivative, atom_derivative, &
352 atomic_weights, context%calculate_derivatives)
353 CASE DEFAULT
354 cpabort("Unknown CDFT partition type.")
355 END SELECT
356 END SUBROUTINE cdft_point_weights
357
358! **************************************************************************************************
359!> \brief Evaluate Becke weights at one point.
360!> \param context ...
361!> \param point ...
362!> \param weights ...
363!> \param point_derivative ...
364!> \param atom_derivative ...
365!> \param atomic_weights ...
366!> \param calculate_derivatives ...
367! **************************************************************************************************
368 SUBROUTINE becke_point_weights(context, point, weights, point_derivative, atom_derivative, &
369 atomic_weights, calculate_derivatives)
370 TYPE(cdft_point_context_type), INTENT(INOUT) :: context
371 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: point
372 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: weights
373 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: point_derivative
374 REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: atom_derivative
375 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: atomic_weights
376 LOGICAL, INTENT(IN) :: calculate_derivatives
377
378 INTEGER :: atom, iatom, iexp, igroup, jatom
379 REAL(kind=dp) :: adjusted_mu, cavity_density, delta, &
380 dmu_factor, f1, f2, f3, mu, numerator, &
381 old_cell, pair_distance, s, sum_cell
382 REAL(kind=dp), DIMENSION(3) :: dmu_i, dmu_j, dmu_point, &
383 dpoint_numerator, ds_i, ds_j, &
384 ds_point, dsum_point, unit_i, unit_j
385
386 weights = 0.0_dp
387 IF (calculate_derivatives) THEN
388 point_derivative = 0.0_dp
389 atom_derivative = 0.0_dp
390 END IF
391 IF (PRESENT(atomic_weights)) atomic_weights = 0.0_dp
392
393 IF (context%cavity_confine) THEN
394 cavity_density = 0.0_dp
395 DO atom = 1, context%natom
396 IF (.NOT. context%constraint_atom(atom)) cycle
397 context%displacement(:, atom) = pbc(context%atom_coords(:, atom), point, context%cell)
398 DO iexp = 1, context%cavity_numexp(atom)
399 cavity_density = cavity_density + context%cavity_amplitude(iexp, atom)* &
400 exp(-context%cavity_alpha(iexp, atom)* &
401 dot_product(context%displacement(:, atom), context%displacement(:, atom)))
402 END DO
403 END DO
404 IF (cavity_density < context%eps_cavity) RETURN
405 END IF
406
407 context%cell_functions = 1.0_dp
408 IF (calculate_derivatives) THEN
409 context%dcell_point = 0.0_dp
410 context%dcell_atom = 0.0_dp
411 END IF
412 DO atom = 1, context%natom
413 context%displacement(:, atom) = pbc(context%atom_coords(:, atom), point, context%cell)
414 context%distances(atom) = norm2(context%displacement(:, atom))
415 END DO
416 DO iatom = 1, context%natom
417 IF (context%distances(iatom) > context%cutoffs(iatom)) THEN
418 context%cell_functions(iatom) = 0.0_dp
419 cycle
420 END IF
421 IF (calculate_derivatives) THEN
422 unit_i = 0.0_dp
423 IF (context%distances(iatom) > 1.0e-14_dp) THEN
424 unit_i = -context%displacement(:, iatom)/context%distances(iatom)
425 END IF
426 END IF
427 DO jatom = 1, context%natom
428 IF (jatom == iatom) cycle
429 pair_distance = norm2(context%pair_vectors(:, iatom, jatom))
430 IF (pair_distance <= 1.0e-14_dp) cycle
431 delta = context%distances(iatom) - context%distances(jatom)
432 mu = delta/pair_distance
433 adjusted_mu = mu + context%aij(iatom, jatom)*(1.0_dp - mu**2)
434 f1 = 1.5_dp*adjusted_mu - 0.5_dp*adjusted_mu**3
435 f2 = 1.5_dp*f1 - 0.5_dp*f1**3
436 f3 = 1.5_dp*f2 - 0.5_dp*f2**3
437 s = 0.5_dp*(1.0_dp - f3)
438 old_cell = context%cell_functions(iatom)
439 IF (calculate_derivatives) THEN
440 dmu_factor = 1.0_dp - 2.0_dp*context%aij(iatom, jatom)*mu
441 unit_j = 0.0_dp
442 IF (context%distances(jatom) > 1.0e-14_dp) THEN
443 unit_j = -context%displacement(:, jatom)/context%distances(jatom)
444 END IF
445 dmu_i = unit_i/pair_distance - &
446 delta*context%pair_vectors(:, iatom, jatom)/pair_distance**3
447 dmu_j = -unit_j/pair_distance + &
448 delta*context%pair_vectors(:, iatom, jatom)/pair_distance**3
449 dmu_point = (-unit_i + unit_j)/pair_distance
450 dmu_factor = -0.5_dp*dmu_factor*1.5_dp*(1.0_dp - adjusted_mu**2)* &
451 1.5_dp*(1.0_dp - f1**2)*1.5_dp*(1.0_dp - f2**2)
452 ds_i = dmu_factor*dmu_i
453 ds_j = dmu_factor*dmu_j
454 ds_point = dmu_factor*dmu_point
455 context%dcell_atom(:, :, iatom) = context%dcell_atom(:, :, iatom)*s
456 context%dcell_point(:, iatom) = context%dcell_point(:, iatom)*s
457 context%dcell_atom(:, iatom, iatom) = &
458 context%dcell_atom(:, iatom, iatom) + old_cell*ds_i
459 context%dcell_atom(:, jatom, iatom) = &
460 context%dcell_atom(:, jatom, iatom) + old_cell*ds_j
461 context%dcell_point(:, iatom) = context%dcell_point(:, iatom) + old_cell*ds_point
462 END IF
463 context%cell_functions(iatom) = old_cell*s
464 END DO
465 END DO
466
467 sum_cell = sum(context%cell_functions)
468 IF (sum_cell <= 1.0e-6_dp) RETURN
469 IF (PRESENT(atomic_weights)) atomic_weights = context%cell_functions/sum_cell
470 IF (calculate_derivatives) THEN
471 dsum_point = sum(context%dcell_point, dim=2)
472 context%datom_sum(:, :) = sum(context%dcell_atom, dim=3)
473 END IF
474 DO igroup = 1, context%ngroup
475 numerator = dot_product(context%coefficients(igroup, :), context%cell_functions)
476 weights(igroup) = numerator/sum_cell
477 IF (calculate_derivatives) THEN
478 dpoint_numerator = matmul(context%dcell_point, context%coefficients(igroup, :))
479 point_derivative(:, igroup) = &
480 (dpoint_numerator*sum_cell - numerator*dsum_point)/sum_cell**2
481 DO atom = 1, context%natom
482 context%datom_numerator(:, atom) = &
483 matmul(context%dcell_atom(:, atom, :), context%coefficients(igroup, :))
484 atom_derivative(:, atom, igroup) = &
485 (context%datom_numerator(:, atom)*sum_cell - &
486 numerator*context%datom_sum(:, atom))/sum_cell**2
487 END DO
488 END IF
489 END DO
490 END SUBROUTINE becke_point_weights
491
492! **************************************************************************************************
493!> \brief Evaluate Hirshfeld weights at one point.
494!> \param context ...
495!> \param point ...
496!> \param weights ...
497!> \param point_derivative ...
498!> \param atom_derivative ...
499!> \param atomic_weights ...
500!> \param calculate_derivatives ...
501! **************************************************************************************************
502 SUBROUTINE hirshfeld_point_weights(context, point, weights, point_derivative, atom_derivative, &
503 atomic_weights, calculate_derivatives)
504 TYPE(cdft_point_context_type), INTENT(INOUT) :: context
505 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: point
506 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: weights
507 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: point_derivative
508 REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: atom_derivative
509 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: atomic_weights
510 LOGICAL, INTENT(IN) :: calculate_derivatives
511
512 INTEGER :: atom, iexp, igroup
513 REAL(kind=dp) :: exponential, numerator, sum_density
514 REAL(kind=dp), DIMENSION(3) :: dpoint_numerator, dsum_point
515
516 weights = 0.0_dp
517 IF (calculate_derivatives) THEN
518 point_derivative = 0.0_dp
519 atom_derivative = 0.0_dp
520 END IF
521 IF (PRESENT(atomic_weights)) atomic_weights = 0.0_dp
522 context%cell_functions = 0.0_dp
523 IF (calculate_derivatives) context%density_atom_derivative = 0.0_dp
524 DO atom = 1, context%natom
525 context%displacement(:, atom) = pbc(context%atom_coords(:, atom), point, context%cell)
526 DO iexp = 1, context%numexp(atom)
527 exponential = context%amplitude(iexp, atom)* &
528 exp(-context%alpha(iexp, atom)* &
529 dot_product(context%displacement(:, atom), context%displacement(:, atom)))
530 context%cell_functions(atom) = context%cell_functions(atom) + exponential
531 IF (calculate_derivatives) THEN
532 context%density_atom_derivative(:, atom) = &
533 context%density_atom_derivative(:, atom) + &
534 2.0_dp*context%alpha(iexp, atom)*context%displacement(:, atom)*exponential
535 END IF
536 END DO
537 END DO
538 sum_density = sum(context%cell_functions)
539 IF (sum_density <= context%eps) THEN
540 RETURN
541 END IF
542 IF (PRESENT(atomic_weights)) atomic_weights = context%cell_functions/sum_density
543 IF (calculate_derivatives) dsum_point = -sum(context%density_atom_derivative, dim=2)
544 DO igroup = 1, context%ngroup
545 numerator = dot_product(context%coefficients(igroup, :), context%cell_functions)
546 weights(igroup) = numerator/sum_density
547 IF (calculate_derivatives) THEN
548 dpoint_numerator(:) = &
549 matmul(context%density_atom_derivative, context%coefficients(igroup, :))
550 dpoint_numerator = -dpoint_numerator
551 point_derivative(:, igroup) = &
552 (dpoint_numerator*sum_density - numerator*dsum_point)/sum_density**2
553 DO atom = 1, context%natom
554 atom_derivative(:, atom, igroup) = &
555 (context%coefficients(igroup, atom) - weights(igroup))* &
556 context%density_atom_derivative(:, atom)/sum_density
557 END DO
558 END IF
559 END DO
560 END SUBROUTINE hirshfeld_point_weights
561
562END MODULE qs_cdft_grid
Definition atom.F:9
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
unit conversion facility
Definition cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1251
Sets up and terminates the global environment variables.
Definition environment.F:17
Calculate Hirshfeld charges and related functions.
subroutine, public create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, radius, radii_list)
creates kind specific shape functions for Hirshfeld charges
The types needed for the calculation of Hirshfeld charges and related functions.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public becke_cutoff_element
integer, parameter, public outer_scf_becke_constraint
integer, parameter, public outer_scf_hirshfeld_constraint
integer, parameter, public becke_cutoff_global
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Define the data structure for the particle information.
Pointwise CDFT partition functions for nonuniform integration grids.
subroutine, public cdft_point_context_create(qs_env, context, calculate_derivatives)
Initialize reusable data for pointwise CDFT partition evaluation.
subroutine, public cdft_point_context_release(context)
Release a pointwise CDFT partition context.
subroutine, public cdft_point_weights(context, point, weights, point_derivative, atom_derivative, atomic_weights)
Evaluate CDFT weights and coordinate derivatives at one point.
Defines CDFT control structures.
Utility subroutines for CDFT calculations.
subroutine, public hirshfeld_constraint_init(qs_env)
Initializes Gaussian Hirshfeld constraints.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
quantities needed for a Hirshfeld based partitioning of real space
Provides all information about a quickstep kind.