(git:0973b94)
Loading...
Searching...
No Matches
efield_utils.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 all routins needed for a nonperiodic electric field
10! **************************************************************************************************
11
16 USE cell_types, ONLY: cell_type,&
17 pbc
20 USE cp_dbcsr_api, ONLY: dbcsr_add,&
26 USE input_constants, ONLY: constant_env,&
30 USE kinds, ONLY: dp
31 USE mathconstants, ONLY: pi,&
32 twopi
35 USE physcon, ONLY: c_light_au
41 USE qs_kind_types, ONLY: get_qs_kind,&
44 USE qs_rho_types, ONLY: qs_rho_get,&
46#include "./base/base_uses.f90"
47
48 IMPLICIT NONE
49
50 PRIVATE
51
52 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'efield_utils'
53
54! *** Public subroutines ***
55
59
60CONTAINS
61
62! **************************************************************************************************
63!> \brief Replace the original implementation of the electric-electronic
64!> interaction in the length gauge. This calculation is no longer done in
65!> the grid but using matrices to match the velocity gauge implementation.
66!> Note: The energy is stored in energy%core and computed later on.
67!> \param qs_env ...
68!> \param calculate_forces add the electronic force from the derivative of the dipole integrals
69!> \author Guillaume Le Breton (02.23)
70! **************************************************************************************************
71
72 SUBROUTINE efield_potential_lengh_gauge(qs_env, calculate_forces)
73
74 TYPE(qs_environment_type), POINTER :: qs_env
75 LOGICAL, INTENT(IN), OPTIONAL :: calculate_forces
76
77 CHARACTER(len=*), PARAMETER :: routinen = 'efield_potential_lengh_gauge'
78
79 INTEGER :: handle, i, iatom, image, natom
80 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
81 LOGICAL :: my_force
82 REAL(kind=dp) :: field(3)
83 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: fdip
84 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
85 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_p, matrix_s, moments
86 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h
87 TYPE(dft_control_type), POINTER :: dft_control
88 TYPE(mp_para_env_type), POINTER :: para_env
89 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
90 TYPE(qs_rho_type), POINTER :: rho
91
92 NULLIFY (dft_control)
93 CALL timeset(routinen, handle)
94
95 CALL get_qs_env(qs_env, &
96 dft_control=dft_control, &
97 matrix_h_kp=matrix_h, &
98 matrix_s=matrix_s)
99
100 NULLIFY (moments)
101 CALL dbcsr_allocate_matrix_set(moments, 3)
102 DO i = 1, 3
103 ALLOCATE (moments(i)%matrix)
104 CALL dbcsr_copy(moments(i)%matrix, matrix_s(1)%matrix, "Moments")
105 CALL dbcsr_set(moments(i)%matrix, 0.0_dp)
106 END DO
107
108 CALL build_local_moment_matrix(qs_env, moments, 1)
109
110 CALL make_field(dft_control, field, qs_env%sim_step, qs_env%sim_time)
111
112 DO i = 1, 3
113 DO image = 1, dft_control%nimages
114 CALL dbcsr_add(matrix_h(1, image)%matrix, moments(i)%matrix, 1.0_dp, field(i))
115 END DO
116 END DO
117
118 CALL dbcsr_deallocate_matrix_set(moments)
119
120 my_force = .false.
121 IF (PRESENT(calculate_forces)) my_force = calculate_forces
122 IF (my_force) THEN
123 ! The dipole integrals are real and symmetric: only the real part of P contributes
124 CALL get_qs_env(qs_env, rho=rho, force=force, atomic_kind_set=atomic_kind_set, &
125 natom=natom, para_env=para_env)
126 CALL qs_rho_get(rho, rho_ao=matrix_p)
127 ALLOCATE (fdip(3, natom))
128 fdip = 0.0_dp
129 CALL qs_efield_dipole_force(qs_env, matrix_p, field, [0.0_dp, 0.0_dp, 0.0_dp], fdip)
130 CALL para_env%sum(fdip)
131 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
132 DO iatom = 1, natom
133 force(kind_of(iatom))%efield(:, atom_of_kind(iatom)) = &
134 force(kind_of(iatom))%efield(:, atom_of_kind(iatom)) + fdip(:, iatom)
135 END DO
136 DEALLOCATE (fdip)
137 END IF
138
139 CALL timestop(handle)
140
141 END SUBROUTINE efield_potential_lengh_gauge
142
143! **************************************************************************************************
144!> \brief computes the amplitude of the efield within a given envelop
145!> \param dft_control ...
146!> \param field ...
147!> \param sim_step ...
148!> \param sim_time ...
149!> \author Florian Schiffmann (02.09)
150! **************************************************************************************************
151
152 SUBROUTINE make_field(dft_control, field, sim_step, sim_time)
153 TYPE(dft_control_type), INTENT(IN) :: dft_control
154 REAL(dp), INTENT(OUT) :: field(3)
155 INTEGER, INTENT(IN) :: sim_step
156 REAL(kind=dp), INTENT(IN) :: sim_time
157
158 INTEGER :: i, lower, nfield, upper
159 REAL(dp) :: e_0, env, nu, pol(3), strength
160 REAL(kind=dp) :: dt
161 TYPE(efield_type), POINTER :: efield
162
163 field = 0._dp
164 nfield = SIZE(dft_control%efield_fields)
165 DO i = 1, nfield
166 efield => dft_control%efield_fields(i)%efield
167 nu = 0.0_dp
168 IF (.NOT. efield%envelop_id == custom_env .AND. efield%wavelength > epsilon(0.0_dp)) THEN
169 nu = c_light_au/(efield%wavelength) !in case of a custom efield we do not need nu
170 END IF
171 e_0 = efield%amplitude
172
173 IF (dot_product(efield%polarisation, efield%polarisation) == 0) THEN
174 pol(:) = 1.0_dp/3.0_dp
175 ELSE
176 pol(:) = efield%polarisation(:)/norm2(efield%polarisation)
177 END IF
178
179 SELECT CASE (efield%envelop_id)
180 CASE (constant_env)
181 IF (sim_step >= efield%envelop_i_vars(1) .AND. &
182 (sim_step <= efield%envelop_i_vars(2) .OR. efield%envelop_i_vars(2) < 0)) THEN
183 field = field + e_0*cos(sim_time*nu*twopi + &
184 efield%phase_offset*pi)*pol(:)
185 END IF
186 CASE (ramp_env)
187 IF (sim_step >= efield%envelop_i_vars(1) .AND. sim_step <= efield%envelop_i_vars(2)) THEN
188 strength = e_0*(sim_step - efield%envelop_i_vars(1))/(efield%envelop_i_vars(2) - efield%envelop_i_vars(1))
189 END IF
190 IF (sim_step >= efield%envelop_i_vars(3) .AND. sim_step <= efield%envelop_i_vars(4)) THEN
191 strength = e_0*(efield%envelop_i_vars(4) - sim_step)/(efield%envelop_i_vars(4) - efield%envelop_i_vars(3))
192 END IF
193 IF (sim_step > efield%envelop_i_vars(4) .AND. efield%envelop_i_vars(4) > 0) strength = 0.0_dp
194 IF (sim_step <= efield%envelop_i_vars(1)) strength = 0.0_dp
195 field = field + strength*cos(sim_time*nu*twopi + &
196 efield%phase_offset*pi)*pol(:)
197 CASE (gaussian_env)
198 env = exp(-0.5_dp*((sim_time - efield%envelop_r_vars(1))/efield%envelop_r_vars(2))**2.0_dp)
199 field = field + e_0*env*cos(sim_time*nu*twopi + &
200 efield%phase_offset*pi)*pol(:)
201 CASE (custom_env)
202 dt = efield%envelop_r_vars(1)
203 IF (sim_time < (SIZE(efield%envelop_r_vars) - 2)*dt) THEN
204 !make a linear interpolation between the two next points
205 lower = floor(sim_time/dt)
206 upper = lower + 1
207 strength = (efield%envelop_r_vars(lower + 2)*(upper*dt - sim_time) &
208 + efield%envelop_r_vars(upper + 2)*(sim_time - lower*dt))/dt
209 ELSE
210 strength = 0.0_dp
211 END IF
212 field = field + strength*pol(:)
213 CASE default
214 END SELECT
215 END DO
216
217 END SUBROUTINE make_field
218
219! **************************************************************************************************
220!> \brief Computes the force and the energy due to a efield on the cores
221!> Note: In the velocity gauge, the energy term is not added because
222!> it would lead to an unbalanced energy (center of negative charge not
223!> involved in the electric energy in this gauge).
224!> \param qs_env ...
225!> \param calculate_forces ...
226!> \author Florian Schiffmann (02.09)
227! **************************************************************************************************
228
229 SUBROUTINE calculate_ecore_efield(qs_env, calculate_forces)
230 TYPE(qs_environment_type), POINTER :: qs_env
231 LOGICAL, OPTIONAL :: calculate_forces
232
233 CHARACTER(len=*), PARAMETER :: routinen = 'calculate_ecore_efield'
234
235 INTEGER :: atom_a, handle, iatom, ikind, natom, &
236 nkind
237 INTEGER, DIMENSION(:), POINTER :: list
238 LOGICAL :: my_force
239 REAL(kind=dp) :: efield_ener, zeff
240 REAL(kind=dp), DIMENSION(3) :: field, r
241 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
242 TYPE(cell_type), POINTER :: cell
243 TYPE(dft_control_type), POINTER :: dft_control
244 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
245 TYPE(qs_energy_type), POINTER :: energy
246 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
247 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
248
249 NULLIFY (dft_control)
250 CALL timeset(routinen, handle)
251 CALL get_qs_env(qs_env, dft_control=dft_control)
252 IF (dft_control%apply_efield_field .OR. dft_control%apply_vector_potential) THEN
253 my_force = .false.
254 IF (PRESENT(calculate_forces)) my_force = calculate_forces
255
256 CALL get_qs_env(qs_env=qs_env, &
257 atomic_kind_set=atomic_kind_set, &
258 qs_kind_set=qs_kind_set, &
259 energy=energy, &
260 particle_set=particle_set, &
261 cell=cell)
262 efield_ener = 0.0_dp
263 nkind = SIZE(atomic_kind_set)
264 CALL make_field(dft_control, field, qs_env%sim_step, qs_env%sim_time)
265
266 DO ikind = 1, SIZE(atomic_kind_set)
267 CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=list, natom=natom)
268 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
269
270 natom = SIZE(list)
271 DO iatom = 1, natom
272 IF (dft_control%apply_efield_field) THEN
273 atom_a = list(iatom)
274 r(:) = pbc(particle_set(atom_a)%r(:), cell)
275 efield_ener = efield_ener - zeff*dot_product(r, field)
276 END IF
277 IF (my_force) THEN
278 CALL get_qs_env(qs_env=qs_env, force=force)
279 force(ikind)%efield(:, iatom) = force(ikind)%efield(:, iatom) - field*zeff
280 END IF
281 END DO
282
283 END DO
284 IF (dft_control%apply_efield_field) energy%efield_core = efield_ener
285 END IF
286 CALL timestop(handle)
287 END SUBROUTINE calculate_ecore_efield
288END MODULE efield_utils
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.
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...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
all routins needed for a nonperiodic electric field
subroutine, public efield_potential_lengh_gauge(qs_env, calculate_forces)
Replace the original implementation of the electric-electronic interaction in the length gauge....
subroutine, public make_field(dft_control, field, sim_step, sim_time)
computes the amplitude of the efield within a given envelop
subroutine, public calculate_ecore_efield(qs_env, calculate_forces)
Computes the force and the energy due to a efield on the cores Note: In the velocity gauge,...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public ramp_env
integer, parameter, public constant_env
integer, parameter, public gaussian_env
integer, parameter, public custom_env
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public twopi
Interface to the message passing library MPI.
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public c_light_au
Definition physcon.F:90
Calculates the energy contribution and the mo_derivative of a static electric field (nonperiodic).
subroutine, public qs_efield_dipole_force(qs_env, matrix_p, field, rpoint, fdip)
Electronic gradient from the nuclear derivative of the dipole integrals, dE/dR = sum_d field_d Tr(P d...
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.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>.
Definition qs_moments.F:14
subroutine, public build_local_moment_matrix(qs_env, moments, nmoments, ref_point, ref_points, basis_type, all_images, minimum_image, neighbor_image, first_component)
...
Definition qs_moments.F:178
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
keeps the density in various representations, keeping track of which ones are valid.