(git:ed6f26b)
Loading...
Searching...
No Matches
qs_efield_berry.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Calculates the energy contribution and the mo_derivative of
10!> a static periodic electric field
11!> \par History
12!> none
13!> \author fschiff (06.2010)
14! **************************************************************************************************
16 USE ai_moments, ONLY: cossin
23 USE cell_types, ONLY: cell_type,&
24 pbc
27 USE cp_cfm_types, ONLY: cp_cfm_create,&
32 USE cp_dbcsr_api, ONLY: dbcsr_copy,&
35 dbcsr_set,&
46 USE cp_fm_types, ONLY: cp_fm_create,&
50 USE kinds, ONLY: dp
51 USE mathconstants, ONLY: gaussi,&
52 pi,&
53 twopi,&
54 z_one,&
55 z_zero
57 USE orbital_pointers, ONLY: ncoset
65 USE qs_kind_types, ONLY: get_qs_kind,&
68 USE qs_mo_types, ONLY: get_mo_set,&
81 USE virial_types, ONLY: virial_type
82#include "./base/base_uses.f90"
83
84 IMPLICIT NONE
85
86 PRIVATE
87
88 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_efield_berry'
89
90 ! *** Public subroutines ***
91
92 PUBLIC :: qs_efield_berry_phase
93
94! **************************************************************************************************
95
96CONTAINS
97
98! **************************************************************************************************
99
100! **************************************************************************************************
101!> \brief ...
102!> \param qs_env ...
103!> \param just_energy ...
104!> \param calculate_forces ...
105! **************************************************************************************************
106 SUBROUTINE qs_efield_berry_phase(qs_env, just_energy, calculate_forces)
107
108 TYPE(qs_environment_type), POINTER :: qs_env
109 LOGICAL, INTENT(IN) :: just_energy, calculate_forces
110
111 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_efield_berry_phase'
112
113 INTEGER :: handle
114 LOGICAL :: s_mstruct_changed
115 TYPE(dft_control_type), POINTER :: dft_control
116
117 CALL timeset(routinen, handle)
118
119 NULLIFY (dft_control)
120 CALL get_qs_env(qs_env, s_mstruct_changed=s_mstruct_changed, &
121 dft_control=dft_control)
122
123 IF (dft_control%apply_period_efield) THEN
124 ! check if the periodic efield should be applied in the current step
125 IF (dft_control%period_efield%start_frame <= qs_env%sim_step .AND. &
126 (dft_control%period_efield%end_frame == -1 .OR. dft_control%period_efield%end_frame >= qs_env%sim_step)) THEN
127
128 IF (s_mstruct_changed) CALL qs_efield_integrals(qs_env)
129 IF (dft_control%period_efield%displacement_field) THEN
130 CALL qs_dispfield_derivatives(qs_env, just_energy, calculate_forces)
131 ELSE
132 CALL qs_efield_derivatives(qs_env, just_energy, calculate_forces)
133 END IF
134 END IF
135 END IF
136
137 CALL timestop(handle)
138
139 END SUBROUTINE qs_efield_berry_phase
140
141! **************************************************************************************************
142!> \brief ...
143!> \param qs_env ...
144! **************************************************************************************************
145 SUBROUTINE qs_efield_integrals(qs_env)
146
147 TYPE(qs_environment_type), POINTER :: qs_env
148
149 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_efield_integrals'
150
151 INTEGER :: handle, i
152 REAL(dp), DIMENSION(3) :: kvec
153 TYPE(cell_type), POINTER :: cell
154 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: cosmat, matrix_s, sinmat
155 TYPE(dft_control_type), POINTER :: dft_control
156 TYPE(efield_berry_type), POINTER :: efield
157
158 CALL timeset(routinen, handle)
159 cpassert(ASSOCIATED(qs_env))
160
161 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
162 NULLIFY (matrix_s)
163 CALL get_qs_env(qs_env=qs_env, efield=efield, cell=cell, matrix_s=matrix_s)
164 CALL init_efield_matrices(efield)
165 ALLOCATE (cosmat(3), sinmat(3))
166 DO i = 1, 3
167 ALLOCATE (cosmat(i)%matrix, sinmat(i)%matrix)
168
169 CALL dbcsr_copy(cosmat(i)%matrix, matrix_s(1)%matrix, 'COS MAT')
170 CALL dbcsr_copy(sinmat(i)%matrix, matrix_s(1)%matrix, 'SIN MAT')
171 CALL dbcsr_set(cosmat(i)%matrix, 0.0_dp)
172 CALL dbcsr_set(sinmat(i)%matrix, 0.0_dp)
173
174 kvec(:) = twopi*cell%h_inv(i, :)
175 CALL build_berry_moment_matrix(qs_env, cosmat(i)%matrix, sinmat(i)%matrix, kvec)
176 END DO
177 CALL set_efield_matrices(efield=efield, cosmat=cosmat, sinmat=sinmat)
178 CALL set_qs_env(qs_env=qs_env, efield=efield)
179 CALL timestop(handle)
180
181 END SUBROUTINE qs_efield_integrals
182
183! **************************************************************************************************
184!> \brief ...
185!> \param qs_env ...
186!> \param just_energy ...
187!> \param calculate_forces ...
188! **************************************************************************************************
189 SUBROUTINE qs_efield_derivatives(qs_env, just_energy, calculate_forces)
190 TYPE(qs_environment_type), POINTER :: qs_env
191 LOGICAL, INTENT(IN) :: just_energy, calculate_forces
192
193 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_efield_derivatives'
194
195 COMPLEX(dp) :: zdet, zdeta, zi(3)
196 INTEGER :: atom_a, atom_b, handle, i, ia, iatom, icol, idir, ikind, irow, iset, ispin, j, &
197 jatom, jkind, jset, ldab, ldsa, ldsb, lsab, n1, n2, nao, natom, ncoa, ncob, nkind, nmo, &
198 nseta, nsetb, sgfa, sgfb
199 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
200 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
201 npgfb, nsgfa, nsgfb
202 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
203 LOGICAL :: found, uniform, use_virial
204 REAL(dp) :: charge, ci(3), cqi(3), dab, dd, &
205 ener_field, f0, fab, fieldpol(3), &
206 focc, fpolvec(3), hmat(3, 3), occ, &
207 qi(3), strength, ti(3)
208 REAL(dp), DIMENSION(3) :: forcea, forceb, kvec, ra, rab, rb, ria
209 REAL(dp), DIMENSION(:, :), POINTER :: cosab, iblock, rblock, sinab, work
210 REAL(dp), DIMENSION(:, :, :), POINTER :: dcosab, dsinab
211 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
212 REAL(kind=dp), DIMENSION(:, :), POINTER :: rpgfa, rpgfb, sphi_a, sphi_b, zeta, zetb
213 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
214 TYPE(block_p_type), DIMENSION(3, 2) :: dcost, dsint
215 TYPE(cell_type), POINTER :: cell
216 TYPE(cp_cfm_type), ALLOCATABLE, DIMENSION(:) :: eigrmat, inv_mat
217 TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
218 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mo_coeff_tmp, mo_derivs_tmp
219 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: inv_work, op_fm_set, opvec
220 TYPE(cp_fm_type), POINTER :: mo_coeff
221 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, mo_derivs
222 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: tempmat
223 TYPE(dbcsr_type), POINTER :: cosmat, mo_coeff_b, sinmat
224 TYPE(dft_control_type), POINTER :: dft_control
225 TYPE(efield_berry_type), POINTER :: efield
226 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
227 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
228 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
229 TYPE(mp_para_env_type), POINTER :: para_env
231 DIMENSION(:), POINTER :: nl_iterator
232 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
233 POINTER :: sab_orb
234 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
235 TYPE(qs_energy_type), POINTER :: energy
236 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
237 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
238 TYPE(qs_kind_type), POINTER :: qs_kind
239 TYPE(virial_type), POINTER :: virial
240
241 CALL timeset(routinen, handle)
242
243 NULLIFY (dft_control, cell, particle_set)
244 CALL get_qs_env(qs_env, dft_control=dft_control, cell=cell, &
245 particle_set=particle_set, virial=virial)
246 NULLIFY (qs_kind_set, efield, para_env, sab_orb)
247 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
248 efield=efield, energy=energy, para_env=para_env, sab_orb=sab_orb)
249
250 ! calculate stress only if forces requested also
251 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
252 use_virial = use_virial .AND. calculate_forces
253 ! disable stress calculation
254 IF (use_virial) THEN
255 cpabort("Stress tensor for periodic E-field not implemented")
256 END IF
257
258 ! if an intensities list is given, select the value for the current step
259 strength = dft_control%period_efield%strength
260 IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
261 strength = dft_control%period_efield%strength_list(mod(qs_env%sim_step &
262 - dft_control%period_efield%start_frame, SIZE(dft_control%period_efield%strength_list)) + 1)
263 END IF
264
265 fieldpol = dft_control%period_efield%polarisation
266 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
267 fieldpol = -fieldpol*strength
268 hmat = cell%hmat(:, :)/twopi
269 DO idir = 1, 3
270 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) + fieldpol(3)*hmat(3, idir)
271 END DO
272
273 ! nuclear contribution
274 natom = SIZE(particle_set)
275 IF (calculate_forces) THEN
276 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, force=force)
277 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
278 END IF
279 zi(:) = cmplx(1._dp, 0._dp, dp)
280 DO ia = 1, natom
281 CALL get_atomic_kind(particle_set(ia)%atomic_kind, kind_number=ikind)
282 CALL get_qs_kind(qs_kind_set(ikind), core_charge=charge)
283 ria = particle_set(ia)%r
284 ria = pbc(ria, cell)
285 DO idir = 1, 3
286 kvec(:) = twopi*cell%h_inv(idir, :)
287 dd = sum(kvec(:)*ria(:))
288 zdeta = cmplx(cos(dd), sin(dd), kind=dp)**charge
289 zi(idir) = zi(idir)*zdeta
290 END DO
291 IF (calculate_forces) THEN
292 IF (para_env%mepos == 0) THEN
293 iatom = atom_of_kind(ia)
294 forcea(:) = fieldpol(:)*charge
295 force(ikind)%efield(:, iatom) = force(ikind)%efield(:, iatom) + forcea(:)
296 END IF
297 END IF
298 IF (use_virial) THEN
299 IF (para_env%mepos == 0) &
300 CALL virial_pair_force(virial%pv_virial, 1.0_dp, forcea, ria)
301 END IF
302 END DO
303 qi = aimag(log(zi))
304
305 ! check uniform occupation
306 NULLIFY (mos)
307 CALL get_qs_env(qs_env=qs_env, mos=mos)
308 DO ispin = 1, dft_control%nspins
309 CALL get_mo_set(mo_set=mos(ispin), maxocc=occ, uniform_occupation=uniform)
310 IF (.NOT. uniform) THEN
311 cpabort("Berry phase moments for non uniform MOs' occupation numbers not implemented")
312 END IF
313 END DO
314
315 NULLIFY (mo_derivs)
316 CALL get_qs_env(qs_env=qs_env, mo_derivs=mo_derivs)
317 ! initialize all work matrices needed
318 ALLOCATE (op_fm_set(2, dft_control%nspins))
319 ALLOCATE (opvec(2, dft_control%nspins))
320 ALLOCATE (eigrmat(dft_control%nspins))
321 ALLOCATE (inv_mat(dft_control%nspins))
322 ALLOCATE (inv_work(2, dft_control%nspins))
323 ALLOCATE (mo_derivs_tmp(SIZE(mo_derivs)))
324 ALLOCATE (mo_coeff_tmp(SIZE(mo_derivs)))
325
326 ! Allocate temp matrices for the wavefunction derivatives
327 DO ispin = 1, dft_control%nspins
328 NULLIFY (tmp_fm_struct, mo_coeff)
329 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nao=nao, nmo=nmo)
330 CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nmo, &
331 ncol_global=nmo, para_env=para_env, context=mo_coeff%matrix_struct%context)
332 CALL cp_fm_create(mo_derivs_tmp(ispin), mo_coeff%matrix_struct)
333 CALL cp_fm_create(mo_coeff_tmp(ispin), mo_coeff%matrix_struct)
334 CALL copy_dbcsr_to_fm(mo_derivs(ispin)%matrix, mo_derivs_tmp(ispin))
335 DO i = 1, SIZE(op_fm_set, 1)
336 CALL cp_fm_create(opvec(i, ispin), mo_coeff%matrix_struct)
337 CALL cp_fm_create(op_fm_set(i, ispin), tmp_fm_struct)
338 CALL cp_fm_create(inv_work(i, ispin), op_fm_set(i, ispin)%matrix_struct)
339 END DO
340 CALL cp_cfm_create(eigrmat(ispin), op_fm_set(1, ispin)%matrix_struct)
341 CALL cp_cfm_create(inv_mat(ispin), op_fm_set(1, ispin)%matrix_struct)
342 CALL cp_fm_struct_release(tmp_fm_struct)
343 END DO
344 ! temp matrices for force calculation
345 IF (calculate_forces) THEN
346 NULLIFY (matrix_s)
347 CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s)
348 ALLOCATE (tempmat(2, dft_control%nspins))
349 DO ispin = 1, dft_control%nspins
350 ALLOCATE (tempmat(1, ispin)%matrix, tempmat(2, ispin)%matrix)
351 CALL dbcsr_copy(tempmat(1, ispin)%matrix, matrix_s(1)%matrix, 'TEMPMAT')
352 CALL dbcsr_copy(tempmat(2, ispin)%matrix, matrix_s(1)%matrix, 'TEMPMAT')
353 CALL dbcsr_set(tempmat(1, ispin)%matrix, 0.0_dp)
354 CALL dbcsr_set(tempmat(2, ispin)%matrix, 0.0_dp)
355 END DO
356 ! integration
357 CALL get_qs_kind_set(qs_kind_set, maxco=ldab, maxsgf=lsab)
358 ALLOCATE (cosab(ldab, ldab), sinab(ldab, ldab), work(ldab, ldab))
359 ALLOCATE (dcosab(ldab, ldab, 3), dsinab(ldab, ldab, 3))
360 lsab = max(ldab, lsab)
361 DO i = 1, 3
362 ALLOCATE (dcost(i, 1)%block(lsab, lsab), dsint(i, 1)%block(lsab, lsab))
363 ALLOCATE (dcost(i, 2)%block(lsab, lsab), dsint(i, 2)%block(lsab, lsab))
364 END DO
365 END IF
366
367 !Start the MO derivative calculation
368 !loop over all cell vectors
369 DO idir = 1, 3
370 ci(idir) = 0.0_dp
371 zi(idir) = z_zero
372 IF (abs(fpolvec(idir)) .GT. 1.0e-12_dp) THEN
373 cosmat => efield%cosmat(idir)%matrix
374 sinmat => efield%sinmat(idir)%matrix
375 !evaluate the expression needed for the derivative (S_berry * C and [C^T S_berry C]^-1)
376 !first step S_berry * C and C^T S_berry C
377 DO ispin = 1, dft_control%nspins ! spin
378 IF (mos(ispin)%use_mo_coeff_b) THEN
379 CALL get_mo_set(mo_set=mos(ispin), nao=nao, mo_coeff_b=mo_coeff_b, nmo=nmo)
380 CALL copy_dbcsr_to_fm(mo_coeff_b, mo_coeff_tmp(ispin))
381 ELSE
382 CALL get_mo_set(mo_set=mos(ispin), nao=nao, mo_coeff=mo_coeff, nmo=nmo)
383 mo_coeff_tmp(ispin) = mo_coeff
384 END IF
385 CALL cp_dbcsr_sm_fm_multiply(cosmat, mo_coeff_tmp(ispin), opvec(1, ispin), ncol=nmo)
386 CALL parallel_gemm("T", "N", nmo, nmo, nao, 1.0_dp, mo_coeff_tmp(ispin), opvec(1, ispin), 0.0_dp, &
387 op_fm_set(1, ispin))
388 CALL cp_dbcsr_sm_fm_multiply(sinmat, mo_coeff_tmp(ispin), opvec(2, ispin), ncol=nmo)
389 CALL parallel_gemm("T", "N", nmo, nmo, nao, 1.0_dp, mo_coeff_tmp(ispin), opvec(2, ispin), 0.0_dp, &
390 op_fm_set(2, ispin))
391 END DO
392 !second step invert C^T S_berry C
393 zdet = z_one
394 DO ispin = 1, dft_control%nspins
395 CALL cp_cfm_scale_and_add_fm(z_zero, eigrmat(ispin), z_one, op_fm_set(1, ispin))
396 CALL cp_cfm_scale_and_add_fm(z_one, eigrmat(ispin), -gaussi, op_fm_set(2, ispin))
397 CALL cp_cfm_set_all(inv_mat(ispin), z_zero, z_one)
398 CALL cp_cfm_solve(eigrmat(ispin), inv_mat(ispin), zdeta)
399 zdet = zdet*zdeta
400 END DO
401 zi(idir) = zdet**occ
402 ci(idir) = aimag(log(zdet**occ))
403
404 IF (.NOT. just_energy) THEN
405 !compute the orbital derivative
406 focc = fpolvec(idir)
407 DO ispin = 1, dft_control%nspins
408 inv_work(1, ispin)%local_data(:, :) = real(inv_mat(ispin)%local_data(:, :), dp)
409 inv_work(2, ispin)%local_data(:, :) = aimag(inv_mat(ispin)%local_data(:, :))
410 CALL get_mo_set(mo_set=mos(ispin), nao=nao, nmo=nmo)
411 CALL parallel_gemm("N", "N", nao, nmo, nmo, focc, opvec(1, ispin), inv_work(2, ispin), &
412 1.0_dp, mo_derivs_tmp(ispin))
413 CALL parallel_gemm("N", "N", nao, nmo, nmo, -focc, opvec(2, ispin), inv_work(1, ispin), &
414 1.0_dp, mo_derivs_tmp(ispin))
415 END DO
416 END IF
417
418 !compute nuclear forces
419 IF (calculate_forces) THEN
420 nkind = SIZE(qs_kind_set)
421 natom = SIZE(particle_set)
422 kvec(:) = twopi*cell%h_inv(idir, :)
423
424 ! calculate: C [C^T S_berry C]^(-1) C^T
425 ! Store this matrix in DBCSR form (only S overlap blocks)
426 DO ispin = 1, dft_control%nspins
427 CALL dbcsr_set(tempmat(1, ispin)%matrix, 0.0_dp)
428 CALL dbcsr_set(tempmat(2, ispin)%matrix, 0.0_dp)
429 CALL get_mo_set(mo_set=mos(ispin), nao=nao, nmo=nmo)
430 CALL parallel_gemm("N", "N", nao, nmo, nmo, 1.0_dp, mo_coeff_tmp(ispin), inv_work(1, ispin), 0.0_dp, &
431 opvec(1, ispin))
432 CALL parallel_gemm("N", "N", nao, nmo, nmo, 1.0_dp, mo_coeff_tmp(ispin), inv_work(2, ispin), 0.0_dp, &
433 opvec(2, ispin))
434 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=tempmat(1, ispin)%matrix, &
435 matrix_v=opvec(1, ispin), matrix_g=mo_coeff_tmp(ispin), ncol=nmo)
436 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=tempmat(2, ispin)%matrix, &
437 matrix_v=opvec(2, ispin), matrix_g=mo_coeff_tmp(ispin), ncol=nmo)
438 END DO
439
440 ! Calculation of derivative integrals (da|eikr|b) and (a|eikr|db)
441 ALLOCATE (basis_set_list(nkind))
442 DO ikind = 1, nkind
443 qs_kind => qs_kind_set(ikind)
444 CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a)
445 IF (ASSOCIATED(basis_set_a)) THEN
446 basis_set_list(ikind)%gto_basis_set => basis_set_a
447 ELSE
448 NULLIFY (basis_set_list(ikind)%gto_basis_set)
449 END IF
450 END DO
451 !
452 CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
453 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
454 CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
455 iatom=iatom, jatom=jatom, r=rab)
456 basis_set_a => basis_set_list(ikind)%gto_basis_set
457 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
458 basis_set_b => basis_set_list(jkind)%gto_basis_set
459 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
460 ! basis ikind
461 first_sgfa => basis_set_a%first_sgf
462 la_max => basis_set_a%lmax
463 la_min => basis_set_a%lmin
464 npgfa => basis_set_a%npgf
465 nseta = basis_set_a%nset
466 nsgfa => basis_set_a%nsgf_set
467 rpgfa => basis_set_a%pgf_radius
468 set_radius_a => basis_set_a%set_radius
469 sphi_a => basis_set_a%sphi
470 zeta => basis_set_a%zet
471 ! basis jkind
472 first_sgfb => basis_set_b%first_sgf
473 lb_max => basis_set_b%lmax
474 lb_min => basis_set_b%lmin
475 npgfb => basis_set_b%npgf
476 nsetb = basis_set_b%nset
477 nsgfb => basis_set_b%nsgf_set
478 rpgfb => basis_set_b%pgf_radius
479 set_radius_b => basis_set_b%set_radius
480 sphi_b => basis_set_b%sphi
481 zetb => basis_set_b%zet
482
483 atom_a = atom_of_kind(iatom)
484 atom_b = atom_of_kind(jatom)
485
486 ldsa = SIZE(sphi_a, 1)
487 ldsb = SIZE(sphi_b, 1)
488 ra(:) = pbc(particle_set(iatom)%r(:), cell)
489 rb(:) = ra + rab
490 dab = sqrt(rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3))
491
492 IF (iatom <= jatom) THEN
493 irow = iatom
494 icol = jatom
495 ELSE
496 irow = jatom
497 icol = iatom
498 END IF
499
500 IF (iatom == jatom .AND. dab < 1.e-10_dp) THEN
501 fab = 1.0_dp*occ
502 ELSE
503 fab = 2.0_dp*occ
504 END IF
505
506 DO i = 1, 3
507 dcost(i, 1)%block = 0.0_dp
508 dsint(i, 1)%block = 0.0_dp
509 dcost(i, 2)%block = 0.0_dp
510 dsint(i, 2)%block = 0.0_dp
511 END DO
512
513 DO iset = 1, nseta
514 ncoa = npgfa(iset)*ncoset(la_max(iset))
515 sgfa = first_sgfa(1, iset)
516 DO jset = 1, nsetb
517 IF (set_radius_a(iset) + set_radius_b(jset) < dab) cycle
518 ncob = npgfb(jset)*ncoset(lb_max(jset))
519 sgfb = first_sgfb(1, jset)
520 ! Calculate the primitive integrals (da|b)
521 CALL cossin(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
522 lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
523 ra, rb, kvec, cosab, sinab, dcosab, dsinab)
524 DO i = 1, 3
525 CALL contract_all(dcost(i, 1)%block, dsint(i, 1)%block, &
526 ncoa, nsgfa(iset), sgfa, sphi_a, ldsa, &
527 ncob, nsgfb(jset), sgfb, sphi_b, ldsb, &
528 dcosab(:, :, i), dsinab(:, :, i), ldab, work, ldab)
529 END DO
530 ! Calculate the primitive integrals (a|db)
531 CALL cossin(lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
532 la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
533 rb, ra, kvec, cosab, sinab, dcosab, dsinab)
534 DO i = 1, 3
535 dcosab(1:ncoa, 1:ncob, i) = transpose(dcosab(1:ncob, 1:ncoa, i))
536 dsinab(1:ncoa, 1:ncob, i) = transpose(dsinab(1:ncob, 1:ncoa, i))
537 CALL contract_all(dcost(i, 2)%block, dsint(i, 2)%block, &
538 ncoa, nsgfa(iset), sgfa, sphi_a, ldsa, &
539 ncob, nsgfb(jset), sgfb, sphi_b, ldsb, &
540 dcosab(:, :, i), dsinab(:, :, i), ldab, work, ldab)
541 END DO
542 END DO
543 END DO
544 forcea = 0.0_dp
545 forceb = 0.0_dp
546 DO ispin = 1, dft_control%nspins
547 NULLIFY (rblock, iblock)
548 CALL dbcsr_get_block_p(matrix=tempmat(1, ispin)%matrix, &
549 row=irow, col=icol, block=rblock, found=found)
550 cpassert(found)
551 CALL dbcsr_get_block_p(matrix=tempmat(2, ispin)%matrix, &
552 row=irow, col=icol, block=iblock, found=found)
553 cpassert(found)
554 n1 = SIZE(rblock, 1)
555 n2 = SIZE(rblock, 2)
556 cpassert(SIZE(iblock, 1) == n1)
557 cpassert(SIZE(iblock, 2) == n2)
558 cpassert(lsab >= n1)
559 cpassert(lsab >= n2)
560 IF (iatom <= jatom) THEN
561 DO i = 1, 3
562 forcea(i) = forcea(i) + sum(rblock(1:n1, 1:n2)*dsint(i, 1)%block(1:n1, 1:n2)) &
563 - sum(iblock(1:n1, 1:n2)*dcost(i, 1)%block(1:n1, 1:n2))
564 forceb(i) = forceb(i) + sum(rblock(1:n1, 1:n2)*dsint(i, 2)%block(1:n1, 1:n2)) &
565 - sum(iblock(1:n1, 1:n2)*dcost(i, 2)%block(1:n1, 1:n2))
566 END DO
567 ELSE
568 DO i = 1, 3
569 forcea(i) = forcea(i) + sum(transpose(rblock(1:n1, 1:n2))*dsint(i, 1)%block(1:n2, 1:n1)) &
570 - sum(transpose(iblock(1:n1, 1:n2))*dcost(i, 1)%block(1:n2, 1:n1))
571 forceb(i) = forceb(i) + sum(transpose(rblock(1:n1, 1:n2))*dsint(i, 2)%block(1:n2, 1:n1)) &
572 - sum(transpose(iblock(1:n1, 1:n2))*dcost(i, 2)%block(1:n2, 1:n1))
573 END DO
574 END IF
575 END DO
576 force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) - fab*fpolvec(idir)*forcea(1:3)
577 force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) - fab*fpolvec(idir)*forceb(1:3)
578 IF (use_virial) THEN
579 f0 = -fab*fpolvec(idir)
580 CALL virial_pair_force(virial%pv_virial, f0, forcea, ra)
581 CALL virial_pair_force(virial%pv_virial, f0, forceb, rb)
582 END IF
583
584 END DO
585 CALL neighbor_list_iterator_release(nl_iterator)
586 DEALLOCATE (basis_set_list)
587
588 END IF
589 END IF
590 END DO
591
592 ! Energy
593 ener_field = 0.0_dp
594 ti = 0.0_dp
595 DO idir = 1, 3
596 ! make sure the total normalized polarization is within [-1:1]
597 cqi(idir) = qi(idir) + ci(idir)
598 IF (cqi(idir) > pi) cqi(idir) = cqi(idir) - twopi
599 IF (cqi(idir) < -pi) cqi(idir) = cqi(idir) + twopi
600 ! now check for log branch
601 IF (abs(efield%polarisation(idir) - cqi(idir)) > pi) THEN
602 ti(idir) = (efield%polarisation(idir) - cqi(idir))/pi
603 DO i = 1, 10
604 cqi(idir) = cqi(idir) + sign(1.0_dp, ti(idir))*twopi
605 IF (abs(efield%polarisation(idir) - cqi(idir)) < pi) EXIT
606 END DO
607 END IF
608 ener_field = ener_field + fpolvec(idir)*cqi(idir)
609 END DO
610
611 ! update the references
612 IF (calculate_forces) THEN
613 ! check for smoothness of energy surface
614 IF (abs(efield%field_energy - ener_field) > pi*abs(sum(fpolvec))) THEN
615 cpwarn("Large change of e-field energy detected. Correct for non-smooth energy surface")
616 END IF
617 efield%field_energy = ener_field
618 efield%polarisation(:) = cqi(:)
619 END IF
620 energy%efield = ener_field
621
622 IF (.NOT. just_energy) THEN
623 ! Add the result to mo_derivativs
624 DO ispin = 1, dft_control%nspins
625 CALL copy_fm_to_dbcsr(mo_derivs_tmp(ispin), mo_derivs(ispin)%matrix)
626 END DO
627 IF (use_virial) THEN
628 ti = 0.0_dp
629 DO i = 1, 3
630 DO j = 1, 3
631 ti(j) = ti(j) + hmat(j, i)*cqi(i)
632 END DO
633 END DO
634 DO i = 1, 3
635 DO j = 1, 3
636 virial%pv_virial(i, j) = virial%pv_virial(i, j) - fieldpol(i)*ti(j)
637 END DO
638 END DO
639 END IF
640 END IF
641
642 DO ispin = 1, dft_control%nspins
643 CALL cp_cfm_release(eigrmat(ispin))
644 CALL cp_cfm_release(inv_mat(ispin))
645 CALL cp_fm_release(mo_derivs_tmp(ispin))
646 IF (mos(ispin)%use_mo_coeff_b) CALL cp_fm_release(mo_coeff_tmp(ispin))
647 DO i = 1, SIZE(op_fm_set, 1)
648 CALL cp_fm_release(opvec(i, ispin))
649 CALL cp_fm_release(op_fm_set(i, ispin))
650 CALL cp_fm_release(inv_work(i, ispin))
651 END DO
652 END DO
653 DEALLOCATE (inv_mat, inv_work, op_fm_set, opvec, eigrmat)
654 DEALLOCATE (mo_coeff_tmp, mo_derivs_tmp)
655
656 IF (calculate_forces) THEN
657 DO ikind = 1, SIZE(atomic_kind_set)
658 CALL para_env%sum(force(ikind)%efield)
659 END DO
660 DEALLOCATE (cosab, sinab, work, dcosab, dsinab)
661 DO i = 1, 3
662 DEALLOCATE (dcost(i, 1)%block, dsint(i, 1)%block)
663 DEALLOCATE (dcost(i, 2)%block, dsint(i, 2)%block)
664 END DO
665 CALL dbcsr_deallocate_matrix_set(tempmat)
666 END IF
667 CALL timestop(handle)
668
669 END SUBROUTINE qs_efield_derivatives
670
671! **************************************************************************************************
672!> \brief ...
673!> \param qs_env ...
674!> \param just_energy ...
675!> \param calculate_forces ...
676! **************************************************************************************************
677 SUBROUTINE qs_dispfield_derivatives(qs_env, just_energy, calculate_forces)
678 TYPE(qs_environment_type), POINTER :: qs_env
679 LOGICAL, INTENT(IN) :: just_energy, calculate_forces
680
681 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_dispfield_derivatives'
682
683 COMPLEX(dp) :: zdet, zdeta, zi(3)
684 INTEGER :: handle, i, ia, iatom, icol, idir, ikind, iodeb, irow, iset, ispin, jatom, jkind, &
685 jset, ldab, ldsa, ldsb, lsab, n1, n2, nao, natom, ncoa, ncob, nkind, nmo, nseta, nsetb, &
686 sgfa, sgfb
687 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
688 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
689 npgfb, nsgfa, nsgfb
690 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
691 LOGICAL :: found, uniform, use_virial
692 REAL(dp) :: charge, ci(3), cqi(3), dab, dd, di(3), ener_field, fab, fieldpol(3), focc, &
693 hmat(3, 3), occ, omega, qi(3), rlog(3), strength, zlog(3)
694 REAL(dp), DIMENSION(3) :: dfilter, forcea, forceb, kvec, ra, rab, &
695 rb, ria
696 REAL(dp), DIMENSION(:, :), POINTER :: cosab, iblock, rblock, sinab, work
697 REAL(dp), DIMENSION(:, :, :), POINTER :: dcosab, dsinab, force_tmp
698 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
699 REAL(kind=dp), DIMENSION(:, :), POINTER :: rpgfa, rpgfb, sphi_a, sphi_b, zeta, zetb
700 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
701 TYPE(block_p_type), DIMENSION(3, 2) :: dcost, dsint
702 TYPE(cell_type), POINTER :: cell
703 TYPE(cp_cfm_type), ALLOCATABLE, DIMENSION(:) :: eigrmat, inv_mat
704 TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
705 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mo_coeff_tmp
706 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: inv_work, mo_derivs_tmp, op_fm_set, opvec
707 TYPE(cp_fm_type), POINTER :: mo_coeff
708 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, mo_derivs
709 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: tempmat
710 TYPE(dbcsr_type), POINTER :: cosmat, mo_coeff_b, sinmat
711 TYPE(dft_control_type), POINTER :: dft_control
712 TYPE(efield_berry_type), POINTER :: efield
713 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
714 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
715 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
716 TYPE(mp_para_env_type), POINTER :: para_env
718 DIMENSION(:), POINTER :: nl_iterator
719 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
720 POINTER :: sab_orb
721 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
722 TYPE(qs_energy_type), POINTER :: energy
723 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
724 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
725 TYPE(qs_kind_type), POINTER :: qs_kind
726 TYPE(virial_type), POINTER :: virial
727
728 CALL timeset(routinen, handle)
729
730 NULLIFY (dft_control, cell, particle_set)
731 CALL get_qs_env(qs_env, dft_control=dft_control, cell=cell, &
732 particle_set=particle_set, virial=virial)
733 NULLIFY (qs_kind_set, efield, para_env, sab_orb)
734 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
735 efield=efield, energy=energy, para_env=para_env, sab_orb=sab_orb)
736
737 ! calculate stress only if forces requested also
738 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
739 use_virial = use_virial .AND. calculate_forces
740 ! disable stress calculation
741 IF (use_virial) THEN
742 cpabort("Stress tensor for periodic D-field not implemented")
743 END IF
744
745 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
746
747 ! if an intensities list is given, select the value for the current step
748 strength = dft_control%period_efield%strength
749 IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
750 strength = dft_control%period_efield%strength_list(mod(qs_env%sim_step &
751 - dft_control%period_efield%start_frame, SIZE(dft_control%period_efield%strength_list)) + 1)
752 END IF
753
754 fieldpol = dft_control%period_efield%polarisation
755 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
756 fieldpol = fieldpol*strength
757
758 omega = cell%deth
759 hmat = cell%hmat(:, :)/(twopi*omega)
760
761 ! nuclear contribution to polarization
762 natom = SIZE(particle_set)
763 IF (calculate_forces) THEN
764 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, force=force)
765 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
766 ALLOCATE (force_tmp(natom, 3, 3))
767 force_tmp = 0.0_dp
768 END IF
769 zi(:) = cmplx(1._dp, 0._dp, dp)
770 DO ia = 1, natom
771 CALL get_atomic_kind(particle_set(ia)%atomic_kind, kind_number=ikind)
772 CALL get_qs_kind(qs_kind_set(ikind), core_charge=charge)
773 ria = particle_set(ia)%r
774 ria = pbc(ria, cell)
775 DO idir = 1, 3
776 kvec(:) = twopi*cell%h_inv(idir, :)
777 dd = sum(kvec(:)*ria(:))
778 zdeta = cmplx(cos(dd), sin(dd), kind=dp)**charge
779 zi(idir) = zi(idir)*zdeta
780 END DO
781 IF (calculate_forces) THEN
782 IF (para_env%mepos == 0) THEN
783 DO i = 1, 3
784 force_tmp(ia, i, i) = force_tmp(ia, i, i) + charge/omega
785 END DO
786 END IF
787 END IF
788 END DO
789 rlog = aimag(log(zi))
790
791 ! check uniform occupation
792 NULLIFY (mos)
793 CALL get_qs_env(qs_env=qs_env, mos=mos)
794 DO ispin = 1, dft_control%nspins
795 CALL get_mo_set(mo_set=mos(ispin), maxocc=occ, uniform_occupation=uniform)
796 IF (.NOT. uniform) THEN
797 cpabort("Berry phase moments for non uniform MO occupation numbers not implemented")
798 END IF
799 END DO
800
801 ! initialize all work matrices needed
802 NULLIFY (mo_derivs)
803 CALL get_qs_env(qs_env=qs_env, mo_derivs=mo_derivs)
804 ALLOCATE (op_fm_set(2, dft_control%nspins))
805 ALLOCATE (opvec(2, dft_control%nspins))
806 ALLOCATE (eigrmat(dft_control%nspins))
807 ALLOCATE (inv_mat(dft_control%nspins))
808 ALLOCATE (inv_work(2, dft_control%nspins))
809 ALLOCATE (mo_derivs_tmp(3, SIZE(mo_derivs)))
810 ALLOCATE (mo_coeff_tmp(SIZE(mo_derivs)))
811
812 ! Allocate temp matrices for the wavefunction derivatives
813 DO ispin = 1, dft_control%nspins
814 NULLIFY (tmp_fm_struct, mo_coeff)
815 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nao=nao, nmo=nmo)
816 CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nmo, &
817 ncol_global=nmo, para_env=para_env, context=mo_coeff%matrix_struct%context)
818 CALL cp_fm_create(mo_coeff_tmp(ispin), mo_coeff%matrix_struct)
819 DO i = 1, 3
820 CALL cp_fm_create(mo_derivs_tmp(i, ispin), mo_coeff%matrix_struct)
821 CALL cp_fm_set_all(matrix=mo_derivs_tmp(i, ispin), alpha=0.0_dp)
822 END DO
823 DO i = 1, SIZE(op_fm_set, 1)
824 CALL cp_fm_create(opvec(i, ispin), mo_coeff%matrix_struct)
825 CALL cp_fm_create(op_fm_set(i, ispin), tmp_fm_struct)
826 CALL cp_fm_create(inv_work(i, ispin), op_fm_set(i, ispin)%matrix_struct)
827 END DO
828 CALL cp_cfm_create(eigrmat(ispin), op_fm_set(1, ispin)%matrix_struct)
829 CALL cp_cfm_create(inv_mat(ispin), op_fm_set(1, ispin)%matrix_struct)
830 CALL cp_fm_struct_release(tmp_fm_struct)
831 END DO
832 ! temp matrices for force calculation
833 IF (calculate_forces) THEN
834 NULLIFY (matrix_s)
835 CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s)
836 ALLOCATE (tempmat(2, dft_control%nspins))
837 DO ispin = 1, dft_control%nspins
838 ALLOCATE (tempmat(1, ispin)%matrix, tempmat(2, ispin)%matrix)
839 CALL dbcsr_copy(tempmat(1, ispin)%matrix, matrix_s(1)%matrix, 'TEMPMAT')
840 CALL dbcsr_copy(tempmat(2, ispin)%matrix, matrix_s(1)%matrix, 'TEMPMAT')
841 CALL dbcsr_set(tempmat(1, ispin)%matrix, 0.0_dp)
842 CALL dbcsr_set(tempmat(2, ispin)%matrix, 0.0_dp)
843 END DO
844 ! integration
845 CALL get_qs_kind_set(qs_kind_set, maxco=ldab, maxsgf=lsab)
846 ALLOCATE (cosab(ldab, ldab), sinab(ldab, ldab), work(ldab, ldab))
847 ALLOCATE (dcosab(ldab, ldab, 3), dsinab(ldab, ldab, 3))
848 lsab = max(lsab, ldab)
849 DO i = 1, 3
850 ALLOCATE (dcost(i, 1)%block(lsab, lsab), dsint(i, 1)%block(lsab, lsab))
851 ALLOCATE (dcost(i, 2)%block(lsab, lsab), dsint(i, 2)%block(lsab, lsab))
852 END DO
853 END IF
854
855 !Start the MO derivative calculation
856 !loop over all cell vectors
857 DO idir = 1, 3
858 zi(idir) = z_zero
859 cosmat => efield%cosmat(idir)%matrix
860 sinmat => efield%sinmat(idir)%matrix
861 !evaluate the expression needed for the derivative (S_berry * C and [C^T S_berry C]^-1)
862 !first step S_berry * C and C^T S_berry C
863 DO ispin = 1, dft_control%nspins ! spin
864 IF (mos(ispin)%use_mo_coeff_b) THEN
865 CALL get_mo_set(mo_set=mos(ispin), nao=nao, mo_coeff_b=mo_coeff_b, nmo=nmo)
866 CALL copy_dbcsr_to_fm(mo_coeff_b, mo_coeff_tmp(ispin))
867 ELSE
868 CALL get_mo_set(mo_set=mos(ispin), nao=nao, mo_coeff=mo_coeff, nmo=nmo)
869 mo_coeff_tmp(ispin) = mo_coeff
870 END IF
871 CALL cp_dbcsr_sm_fm_multiply(cosmat, mo_coeff_tmp(ispin), opvec(1, ispin), ncol=nmo)
872 CALL parallel_gemm("T", "N", nmo, nmo, nao, 1.0_dp, mo_coeff_tmp(ispin), opvec(1, ispin), 0.0_dp, &
873 op_fm_set(1, ispin))
874 CALL cp_dbcsr_sm_fm_multiply(sinmat, mo_coeff_tmp(ispin), opvec(2, ispin), ncol=nmo)
875 CALL parallel_gemm("T", "N", nmo, nmo, nao, 1.0_dp, mo_coeff_tmp(ispin), opvec(2, ispin), 0.0_dp, &
876 op_fm_set(2, ispin))
877 END DO
878 !second step invert C^T S_berry C
879 zdet = z_one
880 DO ispin = 1, dft_control%nspins
881 CALL cp_cfm_scale_and_add_fm(z_zero, eigrmat(ispin), z_one, op_fm_set(1, ispin))
882 CALL cp_cfm_scale_and_add_fm(z_one, eigrmat(ispin), -gaussi, op_fm_set(2, ispin))
883 CALL cp_cfm_set_all(inv_mat(ispin), z_zero, z_one)
884 CALL cp_cfm_solve(eigrmat(ispin), inv_mat(ispin), zdeta)
885 zdet = zdet*zdeta
886 END DO
887 zi(idir) = zdet**occ
888 zlog(idir) = aimag(log(zi(idir)))
889
890 IF (.NOT. just_energy) THEN
891 !compute the orbital derivative
892 DO ispin = 1, dft_control%nspins
893 inv_work(1, ispin)%local_data(:, :) = real(inv_mat(ispin)%local_data(:, :), dp)
894 inv_work(2, ispin)%local_data(:, :) = aimag(inv_mat(ispin)%local_data(:, :))
895 CALL get_mo_set(mo_set=mos(ispin), nao=nao, nmo=nmo)
896 DO i = 1, 3
897 focc = hmat(idir, i)
898 CALL parallel_gemm("N", "N", nao, nmo, nmo, focc, opvec(1, ispin), inv_work(2, ispin), &
899 1.0_dp, mo_derivs_tmp(idir, ispin))
900 CALL parallel_gemm("N", "N", nao, nmo, nmo, -focc, opvec(2, ispin), inv_work(1, ispin), &
901 1.0_dp, mo_derivs_tmp(idir, ispin))
902 END DO
903 END DO
904 END IF
905
906 !compute nuclear forces
907 IF (calculate_forces) THEN
908 nkind = SIZE(qs_kind_set)
909 natom = SIZE(particle_set)
910 kvec(:) = twopi*cell%h_inv(idir, :)
911
912 ! calculate: C [C^T S_berry C]^(-1) C^T
913 ! Store this matrix in DBCSR form (only S overlap blocks)
914 DO ispin = 1, dft_control%nspins
915 CALL dbcsr_set(tempmat(1, ispin)%matrix, 0.0_dp)
916 CALL dbcsr_set(tempmat(2, ispin)%matrix, 0.0_dp)
917 CALL get_mo_set(mo_set=mos(ispin), nao=nao, nmo=nmo)
918 CALL parallel_gemm("N", "N", nao, nmo, nmo, 1.0_dp, mo_coeff_tmp(ispin), inv_work(1, ispin), 0.0_dp, &
919 opvec(1, ispin))
920 CALL parallel_gemm("N", "N", nao, nmo, nmo, 1.0_dp, mo_coeff_tmp(ispin), inv_work(2, ispin), 0.0_dp, &
921 opvec(2, ispin))
922 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=tempmat(1, ispin)%matrix, &
923 matrix_v=opvec(1, ispin), matrix_g=mo_coeff_tmp(ispin), ncol=nmo)
924 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=tempmat(2, ispin)%matrix, &
925 matrix_v=opvec(2, ispin), matrix_g=mo_coeff_tmp(ispin), ncol=nmo)
926 END DO
927
928 ! Calculation of derivative integrals (da|eikr|b) and (a|eikr|db)
929 ALLOCATE (basis_set_list(nkind))
930 DO ikind = 1, nkind
931 qs_kind => qs_kind_set(ikind)
932 CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a)
933 IF (ASSOCIATED(basis_set_a)) THEN
934 basis_set_list(ikind)%gto_basis_set => basis_set_a
935 ELSE
936 NULLIFY (basis_set_list(ikind)%gto_basis_set)
937 END IF
938 END DO
939 !
940 CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
941 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
942 CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
943 iatom=iatom, jatom=jatom, r=rab)
944 basis_set_a => basis_set_list(ikind)%gto_basis_set
945 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
946 basis_set_b => basis_set_list(jkind)%gto_basis_set
947 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
948 ! basis ikind
949 first_sgfa => basis_set_a%first_sgf
950 la_max => basis_set_a%lmax
951 la_min => basis_set_a%lmin
952 npgfa => basis_set_a%npgf
953 nseta = basis_set_a%nset
954 nsgfa => basis_set_a%nsgf_set
955 rpgfa => basis_set_a%pgf_radius
956 set_radius_a => basis_set_a%set_radius
957 sphi_a => basis_set_a%sphi
958 zeta => basis_set_a%zet
959 ! basis jkind
960 first_sgfb => basis_set_b%first_sgf
961 lb_max => basis_set_b%lmax
962 lb_min => basis_set_b%lmin
963 npgfb => basis_set_b%npgf
964 nsetb = basis_set_b%nset
965 nsgfb => basis_set_b%nsgf_set
966 rpgfb => basis_set_b%pgf_radius
967 set_radius_b => basis_set_b%set_radius
968 sphi_b => basis_set_b%sphi
969 zetb => basis_set_b%zet
970
971 ldsa = SIZE(sphi_a, 1)
972 ldsb = SIZE(sphi_b, 1)
973 ra(:) = pbc(particle_set(iatom)%r(:), cell)
974 rb(:) = ra + rab
975 dab = sqrt(rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3))
976
977 IF (iatom <= jatom) THEN
978 irow = iatom
979 icol = jatom
980 ELSE
981 irow = jatom
982 icol = iatom
983 END IF
984
985 IF (iatom == jatom .AND. dab < 1.e-10_dp) THEN
986 fab = 1.0_dp*occ
987 ELSE
988 fab = 2.0_dp*occ
989 END IF
990
991 DO i = 1, 3
992 dcost(i, 1)%block = 0.0_dp
993 dsint(i, 1)%block = 0.0_dp
994 dcost(i, 2)%block = 0.0_dp
995 dsint(i, 2)%block = 0.0_dp
996 END DO
997
998 DO iset = 1, nseta
999 ncoa = npgfa(iset)*ncoset(la_max(iset))
1000 sgfa = first_sgfa(1, iset)
1001 DO jset = 1, nsetb
1002 IF (set_radius_a(iset) + set_radius_b(jset) < dab) cycle
1003 ncob = npgfb(jset)*ncoset(lb_max(jset))
1004 sgfb = first_sgfb(1, jset)
1005 ! Calculate the primitive integrals (da|b)
1006 CALL cossin(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
1007 lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
1008 ra, rb, kvec, cosab, sinab, dcosab, dsinab)
1009 DO i = 1, 3
1010 CALL contract_all(dcost(i, 1)%block, dsint(i, 1)%block, &
1011 ncoa, nsgfa(iset), sgfa, sphi_a, ldsa, &
1012 ncob, nsgfb(jset), sgfb, sphi_b, ldsb, &
1013 dcosab(:, :, i), dsinab(:, :, i), ldab, work, ldab)
1014 END DO
1015 ! Calculate the primitive integrals (a|db)
1016 CALL cossin(lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
1017 la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
1018 rb, ra, kvec, cosab, sinab, dcosab, dsinab)
1019 DO i = 1, 3
1020 dcosab(1:ncoa, 1:ncob, i) = transpose(dcosab(1:ncob, 1:ncoa, i))
1021 dsinab(1:ncoa, 1:ncob, i) = transpose(dsinab(1:ncob, 1:ncoa, i))
1022 CALL contract_all(dcost(i, 2)%block, dsint(i, 2)%block, &
1023 ncoa, nsgfa(iset), sgfa, sphi_a, ldsa, &
1024 ncob, nsgfb(jset), sgfb, sphi_b, ldsb, &
1025 dcosab(:, :, i), dsinab(:, :, i), ldab, work, ldab)
1026 END DO
1027 END DO
1028 END DO
1029 forcea = 0.0_dp
1030 forceb = 0.0_dp
1031 DO ispin = 1, dft_control%nspins
1032 NULLIFY (rblock, iblock)
1033 CALL dbcsr_get_block_p(matrix=tempmat(1, ispin)%matrix, &
1034 row=irow, col=icol, block=rblock, found=found)
1035 cpassert(found)
1036 CALL dbcsr_get_block_p(matrix=tempmat(2, ispin)%matrix, &
1037 row=irow, col=icol, block=iblock, found=found)
1038 cpassert(found)
1039 n1 = SIZE(rblock, 1)
1040 n2 = SIZE(rblock, 2)
1041 cpassert(SIZE(iblock, 1) == n1)
1042 cpassert(SIZE(iblock, 2) == n2)
1043 cpassert(lsab >= n1)
1044 cpassert(lsab >= n2)
1045 IF (iatom <= jatom) THEN
1046 DO i = 1, 3
1047 forcea(i) = forcea(i) + sum(rblock(1:n1, 1:n2)*dsint(i, 1)%block(1:n1, 1:n2)) &
1048 - sum(iblock(1:n1, 1:n2)*dcost(i, 1)%block(1:n1, 1:n2))
1049 forceb(i) = forceb(i) + sum(rblock(1:n1, 1:n2)*dsint(i, 2)%block(1:n1, 1:n2)) &
1050 - sum(iblock(1:n1, 1:n2)*dcost(i, 2)%block(1:n1, 1:n2))
1051 END DO
1052 ELSE
1053 DO i = 1, 3
1054 forcea(i) = forcea(i) + sum(transpose(rblock(1:n1, 1:n2))*dsint(i, 1)%block(1:n2, 1:n1)) &
1055 - sum(transpose(iblock(1:n1, 1:n2))*dcost(i, 1)%block(1:n2, 1:n1))
1056 forceb(i) = forceb(i) + sum(transpose(rblock(1:n1, 1:n2))*dsint(i, 2)%block(1:n2, 1:n1)) &
1057 - sum(transpose(iblock(1:n1, 1:n2))*dcost(i, 2)%block(1:n2, 1:n1))
1058 END DO
1059 END IF
1060 END DO
1061 DO i = 1, 3
1062 force_tmp(iatom, :, i) = force_tmp(iatom, :, i) - fab*hmat(i, idir)*forcea(:)
1063 force_tmp(jatom, :, i) = force_tmp(jatom, :, i) - fab*hmat(i, idir)*forceb(:)
1064 END DO
1065 END DO
1066 CALL neighbor_list_iterator_release(nl_iterator)
1067 DEALLOCATE (basis_set_list)
1068 END IF
1069 END DO
1070
1071 ! make sure the total normalized polarization is within [-1:1]
1072 DO idir = 1, 3
1073 cqi(idir) = rlog(idir) + zlog(idir)
1074 IF (cqi(idir) > pi) cqi(idir) = cqi(idir) - twopi
1075 IF (cqi(idir) < -pi) cqi(idir) = cqi(idir) + twopi
1076 ! now check for log branch
1077 IF (calculate_forces) THEN
1078 IF (abs(efield%polarisation(idir) - cqi(idir)) > pi) THEN
1079 di(idir) = (efield%polarisation(idir) - cqi(idir))/pi
1080 DO i = 1, 10
1081 cqi(idir) = cqi(idir) + sign(1.0_dp, di(idir))*twopi
1082 IF (abs(efield%polarisation(idir) - cqi(idir)) < pi) EXIT
1083 END DO
1084 END IF
1085 END IF
1086 END DO
1087 DO idir = 1, 3
1088 qi(idir) = 0.0_dp
1089 ci(idir) = 0.0_dp
1090 DO i = 1, 3
1091 ci(idir) = ci(idir) + hmat(idir, i)*cqi(i)
1092 END DO
1093 END DO
1094
1095 ! update the references
1096 IF (calculate_forces) THEN
1097 ener_field = sum(ci)
1098 ! check for smoothness of energy surface
1099 IF (abs(efield%field_energy - ener_field) > pi*abs(sum(hmat))) THEN
1100 cpwarn("Large change of e-field energy detected. Correct for non-smooth energy surface")
1101 END IF
1102 efield%field_energy = ener_field
1103 efield%polarisation(:) = cqi(:)
1104 END IF
1105
1106 ! Energy
1107 ener_field = 0.0_dp
1108 DO i = 1, 3
1109 ener_field = ener_field + dfilter(i)*(fieldpol(i) - 2._dp*twopi*ci(i))**2
1110 END DO
1111 energy%efield = 0.25_dp*omega/twopi*ener_field
1112
1113 ! debugging output
1114 IF (para_env%is_source()) THEN
1115 iodeb = -1
1116 IF (iodeb > 0) THEN
1117 WRITE (iodeb, '(A,T61,F20.10)') " Polarisation Quantum: ", 2._dp*twopi*twopi*hmat(3, 3)
1118 WRITE (iodeb, '(A,T21,3F20.10)') " Polarisation: ", 2._dp*twopi*ci(1:3)
1119 WRITE (iodeb, '(A,T21,3F20.10)') " Displacement: ", fieldpol(1:3)
1120 WRITE (iodeb, '(A,T21,3F20.10)') " E-Field: ", ((fieldpol(i) - 2._dp*twopi*ci(i)), i=1, 3)
1121 WRITE (iodeb, '(A,T61,F20.10)') " Disp Free Energy:", energy%efield
1122 END IF
1123 END IF
1124
1125 IF (.NOT. just_energy) THEN
1126 DO i = 1, 3
1127 di(i) = -omega*(fieldpol(i) - 2._dp*twopi*ci(i))*dfilter(i)
1128 END DO
1129 ! Add the result to mo_derivativs
1130 DO ispin = 1, dft_control%nspins
1131 CALL copy_dbcsr_to_fm(mo_derivs(ispin)%matrix, mo_coeff_tmp(ispin))
1132 DO idir = 1, 3
1133 CALL cp_fm_scale_and_add(1.0_dp, mo_coeff_tmp(ispin), di(idir), &
1134 mo_derivs_tmp(idir, ispin))
1135 END DO
1136 END DO
1137 DO ispin = 1, dft_control%nspins
1138 CALL copy_fm_to_dbcsr(mo_coeff_tmp(ispin), mo_derivs(ispin)%matrix)
1139 END DO
1140 END IF
1141
1142 IF (calculate_forces) THEN
1143 DO i = 1, 3
1144 DO ia = 1, natom
1145 CALL get_atomic_kind(particle_set(ia)%atomic_kind, kind_number=ikind)
1146 iatom = atom_of_kind(ia)
1147 force(ikind)%efield(1:3, iatom) = force(ikind)%efield(1:3, iatom) + di(i)*force_tmp(ia, 1:3, i)
1148 END DO
1149 END DO
1150 END IF
1151
1152 DO ispin = 1, dft_control%nspins
1153 CALL cp_cfm_release(eigrmat(ispin))
1154 CALL cp_cfm_release(inv_mat(ispin))
1155 IF (mos(ispin)%use_mo_coeff_b) CALL cp_fm_release(mo_coeff_tmp(ispin))
1156 DO i = 1, 3
1157 CALL cp_fm_release(mo_derivs_tmp(i, ispin))
1158 END DO
1159 DO i = 1, SIZE(op_fm_set, 1)
1160 CALL cp_fm_release(opvec(i, ispin))
1161 CALL cp_fm_release(op_fm_set(i, ispin))
1162 CALL cp_fm_release(inv_work(i, ispin))
1163 END DO
1164 END DO
1165 DEALLOCATE (inv_mat, inv_work, op_fm_set, opvec, eigrmat)
1166 DEALLOCATE (mo_coeff_tmp, mo_derivs_tmp)
1167
1168 IF (calculate_forces) THEN
1169 DO ikind = 1, SIZE(atomic_kind_set)
1170 CALL para_env%sum(force(ikind)%efield)
1171 END DO
1172 DEALLOCATE (force_tmp)
1173 DEALLOCATE (cosab, sinab, work, dcosab, dsinab)
1174 DO i = 1, 3
1175 DEALLOCATE (dcost(i, 1)%block, dsint(i, 1)%block)
1176 DEALLOCATE (dcost(i, 2)%block, dsint(i, 2)%block)
1177 END DO
1178 CALL dbcsr_deallocate_matrix_set(tempmat)
1179 END IF
1180 CALL timestop(handle)
1181
1182 END SUBROUTINE qs_dispfield_derivatives
1183
1184! **************************************************************************************************
1185!> \brief ...
1186!> \param cos_block ...
1187!> \param sin_block ...
1188!> \param ncoa ...
1189!> \param nsgfa ...
1190!> \param sgfa ...
1191!> \param sphi_a ...
1192!> \param ldsa ...
1193!> \param ncob ...
1194!> \param nsgfb ...
1195!> \param sgfb ...
1196!> \param sphi_b ...
1197!> \param ldsb ...
1198!> \param cosab ...
1199!> \param sinab ...
1200!> \param ldab ...
1201!> \param work ...
1202!> \param ldwork ...
1203! **************************************************************************************************
1204 SUBROUTINE contract_all(cos_block, sin_block, &
1205 ncoa, nsgfa, sgfa, sphi_a, ldsa, &
1206 ncob, nsgfb, sgfb, sphi_b, ldsb, &
1207 cosab, sinab, ldab, work, ldwork)
1208
1209 REAL(dp), DIMENSION(:, :), POINTER :: cos_block, sin_block
1210 INTEGER, INTENT(IN) :: ncoa, nsgfa, sgfa
1211 REAL(dp), DIMENSION(:, :), INTENT(IN) :: sphi_a
1212 INTEGER, INTENT(IN) :: ldsa, ncob, nsgfb, sgfb
1213 REAL(dp), DIMENSION(:, :), INTENT(IN) :: sphi_b
1214 INTEGER, INTENT(IN) :: ldsb
1215 REAL(dp), DIMENSION(:, :), INTENT(IN) :: cosab, sinab
1216 INTEGER, INTENT(IN) :: ldab
1217 REAL(dp), DIMENSION(:, :) :: work
1218 INTEGER, INTENT(IN) :: ldwork
1219
1220! Calculate cosine
1221
1222 CALL dgemm("N", "N", ncoa, nsgfb, ncob, 1.0_dp, cosab(1, 1), ldab, &
1223 sphi_b(1, sgfb), ldsb, 0.0_dp, work(1, 1), ldwork)
1224
1225 CALL dgemm("T", "N", nsgfa, nsgfb, ncoa, 1.0_dp, sphi_a(1, sgfa), ldsa, &
1226 work(1, 1), ldwork, 1.0_dp, cos_block(sgfa, sgfb), SIZE(cos_block, 1))
1227
1228 ! Calculate sine
1229 CALL dgemm("N", "N", ncoa, nsgfb, ncob, 1.0_dp, sinab(1, 1), ldab, &
1230 sphi_b(1, sgfb), ldsb, 0.0_dp, work(1, 1), ldwork)
1231
1232 CALL dgemm("T", "N", nsgfa, nsgfb, ncoa, 1.0_dp, sphi_a(1, sgfa), ldsa, &
1233 work(1, 1), ldwork, 1.0_dp, sin_block(sgfa, sgfb), SIZE(sin_block, 1))
1234
1235 END SUBROUTINE contract_all
1236
1237END MODULE qs_efield_berry
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Calculation of the moment integrals over Cartesian Gaussian-type functions.
Definition ai_moments.F:17
subroutine, public cossin(la_max_set, npgfa, zeta, rpgfa, la_min_set, lb_max, npgfb, zetb, rpgfb, lb_min, rac, rbc, kvec, cosab, sinab, dcosab, dsinab)
...
Definition ai_moments.F:339
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
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.
collect pointers to a block of reals
Handles all functions related to the CELL.
Definition cell_types.F:15
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_solve(matrix_a, general_a, determinant)
Solve the system of linear equations A*b=A_general using LU decomposition. Pay attention that both ma...
subroutine, public cp_cfm_scale_and_add_fm(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b). where b is a real matrix (adapted from cp_cf...
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_set(matrix, alpha)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
basic linear algebra operations for full matrices
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
Calculates the energy contribution and the mo_derivative of a static periodic electric field.
subroutine, public qs_efield_berry_phase(qs_env, just_energy, calculate_forces)
...
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, 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, 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, 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, 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, ecoul_1c, rho0_s_rs, rho0_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)
Get the QUICKSTEP environment.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Set the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, basis_type, total_zeff_corr, npgf_seg)
Get attributes of an atomic kind set.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>
Definition qs_moments.F:14
subroutine, public build_berry_moment_matrix(qs_env, cosmat, sinmat, kvec, sab_orb_external, basis_type)
...
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
type for berry phase efield matrices. At the moment only used for cosmat and sinmat
subroutine, public set_efield_matrices(efield, sinmat, cosmat, dipmat)
...
subroutine, public init_efield_matrices(efield)
...
pure subroutine, public virial_pair_force(pv_virial, f0, force, rab)
Computes the contribution to the stress tensor from two-body pair-wise forces.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
Represent a complex full matrix.
keeps the information about the structure of a full matrix
represent a full matrix
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.