Octopus
td_calc.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module td_calc_oct_m
22 use comm_oct_m
23 use debug_oct_m
27 use forces_oct_m
28 use global_oct_m
29 use grid_oct_m
33 use ions_oct_m
34 use iso_c_binding
35 use, intrinsic :: iso_fortran_env
37 use lasers_oct_m
40 use mesh_oct_m
44 use space_oct_m
48 use xc_oct_m
49
50 implicit none
51
52 private
53 public :: &
57
58contains
59
60! ---------------------------------------------------------
70! ---------------------------------------------------------
71 subroutine td_calc_tacc(namespace, space, gr, ions, ext_partners, st, hm, acc, time)
72 type(namespace_t), intent(in) :: namespace
73 class(space_t), intent(in) :: space
74 type(grid_t), intent(in) :: gr
75 type(ions_t), intent(in) :: ions
76 type(partner_list_t), intent(in) :: ext_partners
77 type(states_elec_t), intent(in) :: st
78 type(hamiltonian_elec_t), intent(in) :: hm
79 real(real64), intent(in) :: time
80 real(real64), intent(out) :: acc(:)
81
82 real(real64) :: field(space%dim), x(space%dim)
83 complex(real64), allocatable :: zpsi(:, :), hzpsi(:,:), hhzpsi(:,:), xzpsi(:,:,:), vnl_xzpsi(:,:)
84 integer :: j, k, ik, ist, idim
85 type(lasers_t), pointer :: lasers
86
87 push_sub(td_calc_tacc)
88
89 ! See #683
90 if (family_is_mgga(hm%xc%family) .or. family_is_hybrid(hm%xc)) then
91 call messages_not_implemented("Dipole acceleration with mGGAs and hybrid functionals")
92 end if
93
94 ! The term i<[V_l,p]> + i<[V_nl,p]> may be considered as equal but opposite to the
95 ! force exerted by the electrons on the ions. COMMENT: This has to be thought about.
96 ! Maybe we are forgetting something....
97 call total_force_calculate(space, gr, ions, hm%ep, st, hm%kpoints, acc, hm%lda_u_level)
98
99 ! Adds the laser contribution : i<[V_laser, p]>
100 ! WARNING: this ignores the possibility of non-electric td external fields.
101 field = m_zero
102 lasers => list_get_lasers(ext_partners)
103 if(associated(lasers)) then
104 do j = 1, lasers%no_lasers
105 call laser_electric_field(lasers%lasers(j), field(1:space%dim), time, 0.001_real64)
106 acc(1:space%dim) = acc(1:space%dim) - st%qtot*field(1:space%dim)
107 end do
108 end if
109
110 if (.not. hm%ep%non_local) then
111 pop_sub(td_calc_tacc)
112 return
113 end if
115 ! And now, i<[H,[V_nl,x]]>
116 x = m_zero
117 safe_allocate(zpsi(1:gr%np_part, 1:st%d%dim))
118 safe_allocate(hzpsi(1:gr%np_part, 1:st%d%dim))
119 safe_allocate(hhzpsi(1:3, 1:gr%np_part))
120
121 do ik = st%d%kpt%start, st%d%kpt%end
122 do ist = st%st_start, st%st_end
123
124 call states_elec_get_state(st, gr, ist, ik, zpsi)
125
126 call zhamiltonian_elec_apply_single(hm, namespace, gr, zpsi, hzpsi, ist, ik)
127
128 safe_allocate(xzpsi(1:gr%np_part, 1:st%d%dim, 1:3))
129 safe_allocate(vnl_xzpsi(1:gr%np_part, 1:st%d%dim))
130 xzpsi = m_z0
131 do k = 1, gr%np
132 do j = 1, space%dim
133 xzpsi(k, 1:st%d%dim, j) = gr%x(k, j)*zpsi(k, 1:st%d%dim)
134 end do
135 end do
136
137 do j = 1, space%dim
138 call zhamiltonian_elec_apply_single(hm, namespace, gr, xzpsi(:, :, j), vnl_xzpsi, ist, ik, &
140
141 do idim = 1, st%d%dim
142 x(j) = x(j) - 2*st%occ(ist, ik)*real(zmf_dotp(gr, hzpsi(1:gr%np, idim), vnl_xzpsi(:, idim)), real64)
143 end do
144 end do
145
146 xzpsi = m_z0
147 do k = 1, gr%np
148 do j = 1, space%dim
149 xzpsi(k, 1:st%d%dim, j) = gr%x(k, j)*hzpsi(k, 1:st%d%dim)
150 end do
151 end do
152
153 do j = 1, space%dim
154 call zhamiltonian_elec_apply_single(hm, namespace, gr, xzpsi(:, :, j), vnl_xzpsi, ist, ik, &
156
157 do idim = 1, st%d%dim
158 x(j) = x(j) + 2*st%occ(ist, ik)*real(zmf_dotp(gr, zpsi(:, idim), vnl_xzpsi(:, idim)), real64)
159 end do
160 end do
161 safe_deallocate_a(xzpsi)
162 safe_deallocate_a(vnl_xzpsi)
163
164 end do
165 end do
166 safe_deallocate_a(hzpsi)
167 safe_deallocate_a(hhzpsi)
168
169 if (st%parallel_in_states) then
170 call comm_allreduce(st%mpi_grp, x)
171 end if
172 acc = acc + x
173
174 pop_sub(td_calc_tacc)
175 end subroutine td_calc_tacc
176
177! ---------------------------------------------------------
183! ---------------------------------------------------------
184 subroutine td_calc_tvel(elec_me, kpoints, vel)
185 type(elec_matrix_elements_t), intent(in) :: elec_me
186 type(kpoints_t), intent(in) :: kpoints
187 real(real64), intent(out) :: vel(:)
188
189 real(real64), allocatable :: momentum(:,:,:)
190 integer :: st_start, st_end
191
192 push_sub(td_calc_tvel)
193
194 st_start = elec_me%states%st_start
195 st_end = elec_me%states%st_end
196
197 safe_allocate(momentum(1:elec_me%space%dim, st_start:st_end, elec_me%states%d%kpt%start:elec_me%states%d%kpt%end))
198 call elec_me%momentum_me(kpoints, momentum)
199
200 momentum(1:elec_me%space%dim, st_start:st_end, 1) = &
201 sum(momentum(1:elec_me%space%dim, st_start:st_end, elec_me%states%d%kpt%start:elec_me%states%d%kpt%end), 3)
202 momentum(1:elec_me%space%dim, 1, 1) = sum(momentum(1:elec_me%space%dim, st_start:st_end, 1), 2)
203 vel = momentum(:, 1, 1)
204
205 safe_deallocate_a(momentum)
206
207 pop_sub(td_calc_tvel)
208 end subroutine td_calc_tvel
209
210! ---------------------------------------------------------
213! ---------------------------------------------------------
214 subroutine td_calc_ionch(mesh, st, ch, Nch)
215 type(mesh_t), intent(in) :: mesh
216 type(states_elec_t), intent(in) :: st
217 integer, intent(in) :: nch
218 real(real64), intent(out) :: ch(0:nch)
219
220 integer :: ik, ist, ii, jj, idim, nid
221 real(real64) :: prod, prod0
222 real(real64), allocatable :: n(:), nnot(:)
223 complex(real64), allocatable :: zpsi(:)
224 !combinations
225 integer :: next
226 type(c_ptr) :: c
227 integer, allocatable :: idx0(:), idx(:), idxref(:)
228
229 push_sub(td_calc_ionch)
230
231 safe_allocate( n(1: nch))
232 safe_allocate(nnot(1: nch))
233 safe_allocate(zpsi(1:mesh%np))
234
235 n(:) = m_zero
236 nnot(:)= m_zero
237
238
239 ii = 1
240 do ik = 1, st%nik
241 do ist = 1, st%nst
242 do idim = 1, st%d%dim
243
244 if (st%st_start <= ist .and. ist <= st%st_end .and. &
245 st%d%kpt%start <= ik .and. ik <= st%d%kpt%end) then
246 call states_elec_get_state(st, mesh, idim, ist, ik, zpsi)
247 n(ii) = zmf_nrm2(mesh, zpsi)
248 nnot(ii) = m_one - n(ii)**2
249 end if
250
251 ii = ii + 1
252
253 end do
254 end do
255 end do
256
257 if (st%parallel_in_states) then
258 call comm_allreduce(st%mpi_grp, n)
259 call comm_allreduce(st%mpi_grp, nnot)
260 end if
261
262! print * ,mpi_world%rank, "N =", N(:)
263! print * ,mpi_world%rank, "Nnot =", Nnot(:)
264
265 ch(:) = m_zero
266
267 nid = nch - 1
268 safe_allocate(idx(0:nid))
269 safe_allocate(idxref(0:nid))
270 idxref = (/ (ii, ii = 0, nid) /)
271 do ii = 0, nch
272! print *, "Nch= ", Nch, "ii", ii
273 call loct_combination_init(c, nch, ii)
274 if (ii == 0) then
275 safe_allocate(idx0(0:0))
276 else
277 safe_allocate(idx0(0:ii-1))
278 end if
279! print *,"size(idx0,1)=",size(idx0,1)
280 if (debug%info) then
281 call messages_write("P(")
282 call messages_write(ii)
283 call messages_write(") = 0")
284 call messages_new_line()
285 end if
286 ! Loop over combinations
287 do
288 prod = m_one
289 prod0 = m_one
290 if (debug%info) then
291 call messages_write("P(")
292 call messages_write(ii)
293 call messages_write(") += ")
294 end if
295 call loct_get_combination(c, idx0)
296 idx(:) = idxref(:)
297 do jj = 0, ii-1
298 idx(idx0(jj))= -1
299 if (debug%info) then
300 call messages_write(" No(")
301 call messages_write(idx0(jj)+1)
302 call messages_write(") ")
303 end if
304 prod0 = prod0 * nnot(idx0(jj)+1)
305 end do
306
307 do jj = 0, nid
308 if (idx(jj) >= 0) then
309 if (debug%info) then
310 call messages_write(" N(")
311 call messages_write(idx(jj)+1)
312 call messages_write(") ")
313 end if
314 prod = prod * n(idx(jj)+1)
315 end if
316 end do
317
318 if (debug%info) call messages_new_line()
319
320 ch(ii) = ch(ii) + prod*prod0
321
322 call loct_combination_next(c, next)
323 if (next /= 0) exit
324 end do
325 safe_deallocate_a(idx0)
327
328 if (debug%info) call messages_info()
329 end do
330
331 safe_deallocate_a(idx)
332 safe_deallocate_a(idxref)
333
334
335 safe_deallocate_a(n)
336 safe_deallocate_a(nnot)
337 safe_deallocate_a(zpsi)
338
339 pop_sub(td_calc_ionch)
340 end subroutine td_calc_ionch
341
342
343end module td_calc_oct_m
344
345!! Local Variables:
346!! mode: f90
347!! coding: utf-8
348!! End:
Functions to generate combinations.
Definition: loct_math.F90:293
type(debug_t), save, public debug
Definition: debug.F90:154
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
type(lasers_t) function, pointer, public list_get_lasers(partners)
subroutine, public total_force_calculate(space, gr, ions, ep, st, kpoints, x, lda_u)
This computes the total forces on the ions created by the electrons (it excludes the force due to pos...
Definition: forces.F90:188
real(real64), parameter, public m_zero
Definition: global.F90:187
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public m_one
Definition: global.F90:188
This module implements the underlying real-space grid.
Definition: grid.F90:117
integer, parameter, public term_non_local_potential
subroutine, public zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
This module defines classes and functions for interaction partners.
subroutine, public laser_electric_field(laser, field, time, dt)
Returns a vector with the electric field, no matter whether the laser is described directly as an ele...
Definition: lasers.F90:1187
subroutine, public loct_get_combination(c, comb)
Definition: loct_math.F90:377
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1125
subroutine, public messages_new_line()
Definition: messages.F90:1146
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:624
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public td_calc_tacc(namespace, space, gr, ions, ext_partners, st, hm, acc, time)
Electronic acceleration (to calculate harmonic spectrum...) It is calculated as:
Definition: td_calc.F90:165
subroutine, public td_calc_ionch(mesh, st, ch, Nch)
Multiple ionization probabilities calculated form the KS orbital densities C. Ullrich,...
Definition: td_calc.F90:308
subroutine, public td_calc_tvel(elec_me, kpoints, vel)
Electronic velocity (to calculate harmonic spectrum...) It is calculated as:
Definition: td_calc.F90:278
Definition: xc.F90:114
pure logical function, public family_is_mgga(family, only_collinear)
Is the xc function part of the mGGA family.
Definition: xc.F90:579
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:607
Describes mesh distribution to nodes.
Definition: mesh.F90:186
The states_elec_t class contains all electronic wave functions.