Octopus
propagator_rk.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
23 use comm_oct_m
24 use debug_oct_m
28 use forces_oct_m
30 use grid_oct_m
31 use global_oct_m
35 use ions_oct_m
36 use, intrinsic :: iso_fortran_env
39 use lda_u_oct_m
40 use mesh_oct_m
43 use mpi_oct_m
47 use parser_oct_m
53 use space_oct_m
56 use v_ks_oct_m
58 use xc_oct_m
59
60 implicit none
61
62 private
63
64 public :: &
69
70 class(mesh_t), pointer :: mesh_p
71 type(hamiltonian_elec_t), pointer :: hm_p
72 type(states_elec_t), pointer :: st_p
73 type(propagator_base_t), pointer :: tr_p
74 type(namespace_t), pointer :: namespace_p
75 type(electron_space_t), pointer :: space_p
76 type(partner_list_t), pointer :: ext_partners_p
77 integer :: dim_op
78 real(real64) :: t_op, dt_op
79 real(real64), allocatable :: vpsl1_op(:), vpsl2_op(:)
80 logical :: move_ions_op
81 type(xc_copied_potentials_t) :: vhxc1_op, vhxc2_op
82
83contains
84
85 subroutine td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
86 type(v_ks_t), target, intent(inout) :: ks
87 type(namespace_t), intent(in) :: namespace
88 type(electron_space_t), intent(in) :: space
89 type(hamiltonian_elec_t), target, intent(inout) :: hm
90 type(grid_t), target, intent(in) :: gr
91 type(states_elec_t), target, intent(inout) :: st
92 real(real64), intent(in) :: time
93 real(real64), intent(in) :: dt
94 type(ion_dynamics_t), intent(inout) :: ions_dyn
95 type(ions_t), intent(inout) :: ions
96 type(partner_list_t), intent(in) :: ext_partners
97 type(opt_control_state_t), optional, target, intent(inout) :: qcchi
98
99 type(states_elec_t), pointer :: chi
100 real(real64), pointer :: q(:, :), p(:, :)
101
102 integer :: np_part, np, kp1, kp2, st1, st2, nspin, ik, ist, iatom, ib
103 complex(real64), allocatable :: zphi(:, :, :, :), zchi(:, :, :, :), dvpsi(:, :, :)
104 type(states_elec_t) :: hst, stphi, inh, hchi, stchi
105 logical :: propagate_chi
106 real(real64), allocatable :: pos0(:, :), vel0(:, :), &
107 posk(:, :), velk(:, :), &
108 pos(:, :), vel(:, :), &
109 posfinal(:, :), velfinal(:, :), &
110 pos0t(:, :), vel0t(:, :), &
111 poskt(:, :), velkt(:, :), &
112 post(:, :), velt(:, :), &
113 posfinalt(:, :), velfinalt(:, :), &
114 coforce(:, :)
115
117
118 propagate_chi = present(qcchi)
119 if (propagate_chi) then
120 chi => opt_control_point_qs(qcchi)
121 q => opt_control_point_q(qcchi)
122 p => opt_control_point_p(qcchi)
123 end if
124
125 st1 = st%st_start
126 st2 = st%st_end
127 kp1 = st%d%kpt%start
128 kp2 = st%d%kpt%end
129 np_part = gr%np_part
130 np = gr%np
131 nspin = hm%d%nspin
132
133 safe_allocate(zphi(1:np_part, 1:st%d%dim, st1:st2, kp1:kp2))
134 if (propagate_chi) then
135 safe_allocate(zchi(1:np_part, 1:st%d%dim, st1:st2, kp1:kp2))
136 end if
137 if (ion_dynamics_ions_move(ions_dyn)) then
138 safe_allocate(pos(1:ions%space%dim, 1:ions%natoms))
139 safe_allocate(vel(1:ions%space%dim, 1:ions%natoms))
140 safe_allocate(pos0(1:ions%space%dim, 1:ions%natoms))
141 safe_allocate(vel0(1:ions%space%dim, 1:ions%natoms))
142 safe_allocate(posk(1:ions%space%dim, 1:ions%natoms))
143 safe_allocate(velk(1:ions%space%dim, 1:ions%natoms))
144 safe_allocate(posfinal(1:ions%space%dim, 1:ions%natoms))
145 safe_allocate(velfinal(1:ions%space%dim, 1:ions%natoms))
146
147 if (propagate_chi) then
148 safe_allocate(post(1:ions%space%dim, 1:ions%natoms))
149 safe_allocate(velt(1:ions%space%dim, 1:ions%natoms))
150 safe_allocate(pos0t(1:ions%space%dim, 1:ions%natoms))
151 safe_allocate(vel0t(1:ions%space%dim, 1:ions%natoms))
152 safe_allocate(poskt(1:ions%space%dim, 1:ions%natoms))
153 safe_allocate(velkt(1:ions%space%dim, 1:ions%natoms))
154 safe_allocate(posfinalt(1:ions%space%dim, 1:ions%natoms))
155 safe_allocate(velfinalt(1:ions%space%dim, 1:ions%natoms))
156 safe_allocate(coforce(1:ions%natoms, 1:ions%space%dim))
157 end if
158 end if
159
160 call states_elec_copy(hst, st)
161 call states_elec_copy(stphi, st)
162 call states_elec_get_state(st, gr, zphi)
164 if (propagate_chi) then
165 call states_elec_copy(hchi, chi)
166 call states_elec_copy(stchi, chi)
167 call states_elec_get_state(chi, gr, zchi)
168 end if
170 if (ion_dynamics_ions_move(ions_dyn)) then
171 pos0 = ions%pos
172 vel0 = ions%vel
173 posfinal = pos0
174 velfinal = vel0
175
176 if (propagate_chi) then
177 do iatom = 1, ions%natoms
178 pos0t(1:ions%space%dim, iatom) = q(iatom, 1:ions%space%dim)
179 vel0t(1:ions%space%dim, iatom) = p(iatom, 1:ions%space%dim) / ions%mass(iatom)
180 end do
181 posfinalt = pos0t
182 velfinalt = vel0t
183 end if
184 end if
185
186!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
187 ! Stage 1.
188 !
189
190 !
191 call states_elec_set_state(stphi, gr, zphi)
192 if (propagate_chi) then
193 call states_elec_set_state(stchi, gr, zchi)
194 end if
195 if (ion_dynamics_ions_move(ions_dyn)) then
196 pos = pos0
197 vel = vel0
198 if (propagate_chi) then
199 post = pos0t
200 velt = vel0t
201 end if
202 end if
203
204 call f_psi(time - dt)
205 if (propagate_chi) call f_chi(time - dt)
206 if (ion_dynamics_ions_move(ions_dyn)) call f_ions(time - dt)
207
208 call update_state(m_one/6.0_real64)
209
210!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
211 ! Stage 2.
212
213 call states_elec_set_state(stphi, gr, zphi)
214 if (propagate_chi) then
215 call states_elec_set_state(stchi, gr, zchi)
216 end if
217
218 do ik = stphi%d%kpt%start, stphi%d%kpt%end
219 do ib = stphi%group%block_start, stphi%group%block_end
220 call batch_axpy(gr%np, -m_half*m_zi*dt, hst%group%psib(ib, ik), stphi%group%psib(ib, ik))
221 if (propagate_chi) then
222 call batch_axpy(gr%np, -m_half*m_zi*dt, hchi%group%psib(ib, ik), stchi%group%psib(ib, ik))
223 end if
224 end do
225 end do
226
227 if (ion_dynamics_ions_move(ions_dyn)) then
228 pos = pos0 + m_half * posk
229 vel = vel0 + m_half * velk
230 if (propagate_chi) then
231 post = pos0t + m_half * poskt
232 velt = vel0t + m_half * velkt
233 end if
234 end if
235
236 call f_psi(time-m_half*dt)
237 if (propagate_chi) call f_chi(time-m_half*dt)
238 if (ion_dynamics_ions_move(ions_dyn)) call f_ions(time-m_half*dt)
240
241!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
242 ! Stage 3.
243
244 call states_elec_set_state(stphi, gr, zphi)
245 if (propagate_chi) then
246 call states_elec_set_state(stchi, gr, zchi)
247 end if
248
249 do ik = stphi%d%kpt%start, stphi%d%kpt%end
250 do ib = stphi%group%block_start, stphi%group%block_end
251 call batch_axpy(gr%np, -m_half*m_zi*dt, hst%group%psib(ib, ik), stphi%group%psib(ib, ik))
252 if (propagate_chi) then
253 call batch_axpy(gr%np, -m_half*m_zi*dt, hchi%group%psib(ib, ik), stchi%group%psib(ib, ik))
254 end if
255 end do
256 end do
257
258 if (ion_dynamics_ions_move(ions_dyn)) then
259 pos = pos0 + m_half * posk
260 vel = vel0 + m_half * velk
261 if (propagate_chi) then
262 post = pos0t + m_half * poskt
263 velt = vel0t + m_half * velkt
264 end if
265 end if
266
267 call f_psi(time-m_half*dt)
268 if (propagate_chi) call f_chi(time-m_half*dt)
269 if (ion_dynamics_ions_move(ions_dyn)) call f_ions(time-m_half*dt)
270
272
273!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
274 ! Stage 4.
275
276 call states_elec_set_state(stphi, gr, zphi)
277 if (propagate_chi) then
278 call states_elec_set_state(stchi, gr, zchi)
279 end if
280
281 do ik = stphi%d%kpt%start, stphi%d%kpt%end
282 do ib = stphi%group%block_start, stphi%group%block_end
283 call batch_axpy(gr%np, -m_zi*dt, hst%group%psib(ib, ik), stphi%group%psib(ib, ik))
284 if (propagate_chi) then
285 call batch_axpy(gr%np, -m_zi*dt, hchi%group%psib(ib, ik), stchi%group%psib(ib, ik))
286 end if
287 end do
288 end do
289
290 if (ion_dynamics_ions_move(ions_dyn)) then
291 pos = pos0 + posk
292 vel = vel0 + velk
293 if (propagate_chi) then
294 post = pos0t + poskt
295 velt = vel0t + velkt
296 end if
297 end if
298
299 call f_psi(time)
300 if (propagate_chi) call f_chi(time)
301 if (ion_dynamics_ions_move(ions_dyn)) call f_ions(time)
302
303 call update_state(m_one / 6.0_real64)
304
305!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
306 ! Collect the results.
307
308 call density_calc(st, gr, st%rho)
309 if (ion_dynamics_ions_move(ions_dyn)) then
310 ions%pos = posfinal
311 ions%vel = velfinal
312 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time)
313 !call forces_calculate(gr, namespace, ions, hm, stphi, time, dt)
314 call ions%update_kinetic_energy()
315
316 if (propagate_chi) then
317 do iatom = 1, ions%natoms
318 q(iatom, 1:ions%space%dim) = posfinalt(1:ions%space%dim, iatom)
319 p(iatom, 1:ions%space%dim) = ions%mass(iatom) * velfinalt(1:ions%space%dim, iatom)
320 end do
321 end if
322 end if
323
324 call states_elec_end(hst)
325 call states_elec_end(stphi)
326 safe_deallocate_a(zphi)
327 if (propagate_chi) then
328 call states_elec_end(hchi)
329 call states_elec_end(stchi)
330 safe_deallocate_a(zchi)
331 nullify(chi)
332 nullify(p)
333 nullify(q)
334 end if
335
336 if (ion_dynamics_ions_move(ions_dyn)) then
337 safe_deallocate_a(pos)
338 safe_deallocate_a(vel)
339 safe_deallocate_a(pos0)
340 safe_deallocate_a(vel0)
341 safe_deallocate_a(posk)
342 safe_deallocate_a(velk)
343 safe_deallocate_a(posfinal)
344 safe_deallocate_a(velfinal)
345
346 if (propagate_chi) then
347 safe_deallocate_a(post)
348 safe_deallocate_a(velt)
349 safe_deallocate_a(pos0t)
350 safe_deallocate_a(vel0t)
351 safe_deallocate_a(poskt)
352 safe_deallocate_a(velkt)
353 safe_deallocate_a(posfinalt)
354 safe_deallocate_a(velfinalt)
355 safe_deallocate_a(coforce)
356 end if
357 end if
359
360 contains
361
362 subroutine f_psi(tau)
363 real(real64), intent(in) :: tau
364
365 if (ion_dynamics_ions_move(ions_dyn)) then
366 ions%pos = pos
367 ions%vel = vel
368 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, stphi, time = tau)
369 end if
370 if (.not. oct_exchange_enabled(hm%oct_exchange)) then
371 call density_calc(stphi, gr, stphi%rho)
372 call v_ks_calc(ks, namespace, space, hm, stphi, ions, ext_partners, &
373 calc_current = list_has_gauge_field(ext_partners), &
374 time = tau, calc_energy = .false., calc_eigenval = .false.)
375 else
376 call hm%update(gr, namespace, space, ext_partners, time = tau)
377 end if
378 call lda_u_update_occ_matrices(hm%lda_u, namespace, gr, st, hm%hm_base, hm%phase, hm%energy)
379 call zhamiltonian_elec_apply_all(hm, namespace, gr, stphi, hst)
380 end subroutine f_psi
381
382 subroutine f_ions(tau)
383 real(real64), intent(in) :: tau
384
385 call forces_calculate(gr, namespace, ions, hm, ext_partners, stphi, ks, t = tau, dt = dt)
386 do iatom = 1, ions%natoms
387 posk(:, iatom) = dt * vel(:, iatom)
388 velk(:, iatom) = dt * ions%tot_force(:, iatom) / ions%mass(iatom)
389 end do
390 if (propagate_chi) then
391 call forces_costate_calculate(gr, namespace, ions, hm, stphi, stchi, coforce, transpose(post))
392 do iatom = 1, ions%natoms
393 poskt(:, iatom) = dt * velt(:, iatom)
394 velkt(:, iatom) = dt * coforce(iatom, :) / ions%mass(iatom)
395 end do
396 end if
397 end subroutine f_ions
398
399 subroutine f_chi(tau)
400 real(real64), intent(in) :: tau
401
402 if (hm%theory_level /= independent_particles) call oct_exchange_set(hm%oct_exchange, stphi, gr)
403 call prepare_inh()
405
406 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, tau)
407
408 call zhamiltonian_elec_apply_all(hm, namespace, gr, stchi, hchi)
410
411
412 call apply_inh()
413 if (hm%theory_level /= independent_particles) call oct_exchange_remove(hm%oct_exchange)
415 end subroutine f_chi
416
417 subroutine apply_inh()
418 integer :: ib
419
420 if (hamiltonian_elec_inh_term(hm)) then
421 do ik = kp1, kp2
422 do ib = 1, st%group%block_start, st%group%block_end
423 call batch_axpy(np, m_zi, hm%inh_st%group%psib(ib, ik), hchi%group%psib(ib, ik))
424 end do
425 end do
426 end if
427 end subroutine apply_inh
428
429 subroutine prepare_inh()
430 integer :: idir
431 complex(real64), allocatable :: psi(:, :), inhpsi(:, :)
432 type(perturbation_ionic_t), pointer :: pert
433
434 if (ion_dynamics_ions_move(ions_dyn)) then
435 call states_elec_copy(inh, st)
436
437 safe_allocate(psi(1:gr%np_part, 1:st%d%dim))
438 safe_allocate(inhpsi(1:gr%np_part, 1:st%d%dim))
439 safe_allocate(dvpsi(1:gr%np_part, 1:st%d%dim, 1:space%dim))
440
441 do ik = 1, st%nik
442 do ist = 1, st%nst
443
444 inhpsi = m_z0
445 call states_elec_get_state(stphi, gr, ist, ik, psi)
446
447 do iatom = 1, ions%natoms
448 do idir = 1, space%dim
449 pert => perturbation_ionic_t(namespace, ions)
450 call pert%setup_atom(iatom)
451 call pert%setup_dir(idir)
452 call pert%zapply(namespace, space, gr, hm, ik, psi(:, :), dvpsi(:, :, idir))
453 dvpsi(:, :, idir) = - dvpsi(:, :, idir)
454 inhpsi(1:gr%np, 1:stphi%d%dim) = inhpsi(1:gr%np, 1:stphi%d%dim) &
455 + st%occ(ist, ik)*post(idir, iatom)*dvpsi(1:gr%np, 1:stphi%d%dim, idir)
456 safe_deallocate_p(pert)
457 end do
458 end do
459
460 call states_elec_set_state(inh, gr, ist, ik, inhpsi)
461
462 end do
463 end do
464
465 call hamiltonian_elec_set_inh(hm, inh)
466 call states_elec_end(inh)
467
468 safe_deallocate_a(psi)
469 safe_deallocate_a(inhpsi)
470 safe_deallocate_a(dvpsi)
471
472 end if
473 end subroutine prepare_inh
474
475 subroutine update_state(epsilon)
476 real(real64), intent(in) :: epsilon
477
478 do ik = stphi%d%kpt%start, stphi%d%kpt%end
479 do ib = stphi%group%block_start, stphi%group%block_end
480 call batch_axpy(gr%np, -m_zi*dt*epsilon, hst%group%psib(ib, ik), st%group%psib(ib, ik))
481 if (propagate_chi) then
482 call batch_axpy(gr%np, -m_zi*dt*epsilon, hchi%group%psib(ib, ik), chi%group%psib(ib, ik))
483 end if
484 end do
485 end do
486
487 if (ion_dynamics_ions_move(ions_dyn)) then
488 posfinal = posfinal + posk * epsilon
489 velfinal = velfinal + velk * epsilon
490 if (propagate_chi) then
491 posfinalt = posfinalt + poskt * epsilon
492 velfinalt = velfinalt + velkt * epsilon
493 end if
494 end if
495 end subroutine update_state
496
497 end subroutine td_explicit_runge_kutta4
498
499
500 subroutine td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
501 type(v_ks_t), target, intent(inout) :: ks
502 type(namespace_t), target, intent(in) :: namespace
503 type(electron_space_t), target, intent(in) :: space
504 type(hamiltonian_elec_t), target, intent(inout) :: hm
505 type(grid_t), target, intent(in) :: gr
506 type(states_elec_t), target, intent(inout) :: st
507 type(propagator_base_t), target, intent(inout) :: tr
508 real(real64), intent(in) :: time
509 real(real64), intent(in) :: dt
510 type(ion_dynamics_t), intent(inout) :: ions_dyn
511 type(ions_t), intent(inout) :: ions
512 type(partner_list_t), target, intent(in) :: ext_partners
513
514 integer :: np_part, np, kp1, kp2, st1, st2, nspin, ik, ist, idim, j, ip
515 integer :: i
516 real(real64) :: dres
517 complex(real64), allocatable :: zphi(:, :, :, :)
518 complex(real64), allocatable :: zpsi(:), rhs(:)
519 complex(real64), allocatable :: k2(:, :, :, :), oldk2(:, :, :, :), rhs1(:, :, :, :)
520 complex(real64), allocatable :: inhpsi(:)
521 type(ion_state_t) :: ions_state
523 push_sub(td_runge_kutta2)
524
525 st1 = st%st_start
526 st2 = st%st_end
527 kp1 = st%d%kpt%start
528 kp2 = st%d%kpt%end
529 np_part = gr%np_part
530 np = gr%np
531 nspin = hm%d%nspin
532 move_ions_op = ion_dynamics_ions_move(ions_dyn)
533
534 sp_np = np
535 sp_dim = st%d%dim
536 sp_st1 = st1
537 sp_st2 = st2
538 sp_kp1 = kp1
539 sp_kp2 = kp2
540 sp_parallel = st%parallel_in_states .or. st%d%kpt%parallel
541 if (sp_parallel) call mpi_grp_copy(sp_grp, st%st_kpt_mpi_grp)
542
543 ! define pointer and variables for usage in td_rk2op, td_rk2opt routines
544 mesh_p => gr
545 hm_p => hm
546 tr_p => tr
547 st_p => st
548 namespace_p => namespace
549 space_p => space
550 ext_partners_p => ext_partners
551 dt_op = dt
552 t_op = time - dt/m_two
553 dim_op = st%d%dim
554
555 safe_allocate(k2(1:np_part, 1:st%d%dim, st1:st2, kp1:kp2))
556 safe_allocate(oldk2(1:np_part, 1:st%d%dim, st1:st2, kp1:kp2))
557 safe_allocate(zphi(1:gr%np_part, st%d%dim, st1:st2, kp1:kp2))
558 safe_allocate(rhs1(1:np_part, 1:st%d%dim, st1:st2, kp1:kp2))
559 safe_allocate(rhs(1:tr%tdsk_size))
560 safe_allocate(zpsi(1:tr%tdsk_size))
561 safe_allocate(vpsl1_op(1:np))
562
563 ! First, we get the state that we want to propagate. For the moment being, only one state.
564 do ik = kp1, kp2
565 do ist = st1, st2
566 call states_elec_get_state(st, gr, ist, ik, zphi(:, :, ist, ik))
567 end do
568 end do
569
570 if (oct_exchange_enabled(hm%oct_exchange)) then
571 call oct_exchange_prepare(hm%oct_exchange, gr, zphi, hm%xc, hm%psolver, namespace)
572 end if
573
574 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time - dt)
575
576 rhs1 = m_z0
577 do ik = kp1, kp2
578 do ist = st1, st2
579 call zhamiltonian_elec_apply_single(hm_p, namespace, mesh_p, zphi(:, :, ist, ik), rhs1(:, :, ist, ik), ist, ik)
580 end do
581 end do
582 do ik = kp1, kp2
583 do ist = st1, st2
584 if (oct_exchange_enabled(hm%oct_exchange)) then
585 call oct_exchange_operator(hm%oct_exchange, namespace, gr, rhs1(:, :, ist, ik), ist, ik)
586 end if
587 end do
588 end do
589
590 rhs1 = zphi - m_zi * m_half * dt * rhs1
591
592 if (hamiltonian_elec_inh_term(hm)) then
593 safe_allocate(inhpsi(1:gr%np))
594 do ik = kp1, kp2
595 do ist = st1, st2
596 do idim = 1, st%d%dim
597 call states_elec_get_state(hm%inh_st, gr, idim, ist, ik, inhpsi)
598 do ip = 1, gr%np
599 rhs1(ip, idim, ist, ik) = rhs1(ip, idim, ist, ik) + dt * inhpsi(ip)
600 end do
601 end do
602 end do
603 end do
604 safe_deallocate_a(inhpsi)
605 end if
606
607 k2 = zphi
608
609 i = 1
610 do
611 oldk2 = k2
612
613 ! Set the Hamiltonian at the final time of the propagation
614 if (.not. oct_exchange_enabled(hm_p%oct_exchange)) then
615 do ik = kp1, kp2
616 do ist = st1, st2
617 call states_elec_set_state(st, gr, ist, ik, k2(:, :, ist, ik))
618 end do
619 end do
620 call density_calc(st, gr, st%rho)
621 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
622 calc_current = list_has_gauge_field(ext_partners),&
623 calc_energy = .false., calc_eigenval = .false.)
624 end if
625 if (ion_dynamics_ions_move(ions_dyn)) then
626 call ion_dynamics_save_state(ions_dyn, ions, ions_state)
627 call ion_dynamics_propagate(ions_dyn, ions, time, dt, namespace)
628 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = time)
629 vpsl1_op = hm%ep%vpsl
630 end if
631
632 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
633
634 if (.not. oct_exchange_enabled(hm_p%oct_exchange)) then
635 if (i == 1) then
636 call hm%ks_pot%get_interpolated_potentials(tr%vks_old, 0, storage=vhxc1_op)
637 i = i + 1
638 else
639 call hm%ks_pot%store_potentials(vhxc1_op)
640 end if
641 t_op = time
642 else
643 call hm%ks_pot%store_potentials(vhxc1_op)
644 end if
645
646 if (ion_dynamics_ions_move(ions_dyn)) then
647 call ion_dynamics_restore_state(ions_dyn, ions, ions_state)
648 end if
649
650 j = 1
651 do ik = kp1, kp2
652 do ist = st1, st2
653 do idim = 1, st%d%dim
654 rhs(j:j+np-1) = rhs1(1:np, idim, ist, ik)
655 j = j + np
656 end do
657 end do
658 end do
659
660 ! Now we populate an initial guess for the equation.
661 j = 1
662 do ik = kp1, kp2
663 do ist = st1, st2
664 do idim = 1, st%d%dim
665 zpsi(j:j+np-1) = k2(1:np, idim, ist, ik)
666 j = j + np
667 end do
668 end do
669 end do
670
671 t_op = time - dt
672 call zsparskit_solver_run(namespace, tr%tdsk, td_rk2op, td_rk2opt, zpsi, rhs)
673
674 k2 = m_z0
675 j = 1
676 do ik = kp1, kp2
677 do ist = st1, st2
678 do idim = 1, st%d%dim
679 k2(1:np, idim, ist, ik) = zpsi(j:j+np-1)
680 j = j + np
681 end do
682 end do
683 end do
684
685 dres = m_zero
686 do ik = kp1, kp2
687 do ist = st1, st2
688 do idim = 1, st%d%dim
689 dres = dres + (zmf_nrm2(gr, k2(:, idim, ist, ik) - oldk2(:, idim, ist, ik), reduce = .false.))**2
690 end do
691 end do
692 end do
693
694 call comm_allreduce(st%dom_st_kpt_mpi_grp, dres)
695
696 if (sqrt(dres) < tr%scf_threshold) exit
697 end do
698
699 zphi = k2
700 do ik = kp1, kp2
701 do ist = st1, st2
702 call states_elec_set_state(st, gr, ist, ik, zphi(:, :, ist, ik))
703 end do
704 end do
705
706 call density_calc(st, gr, st%rho)
707
708 safe_deallocate_a(k2)
709 safe_deallocate_a(oldk2)
710 safe_deallocate_a(zphi)
711 safe_deallocate_a(rhs1)
712 safe_deallocate_a(zpsi)
713 safe_deallocate_a(rhs)
714 safe_deallocate_a(vpsl1_op)
715
716 pop_sub(td_runge_kutta2)
717 end subroutine td_runge_kutta2
718
719 !----------------------------------------------------------------------------
720
721 subroutine td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
722 type(v_ks_t), target, intent(inout) :: ks
723 type(namespace_t), target, intent(in) :: namespace
724 type(electron_space_t), target, intent(in) :: space
725 type(hamiltonian_elec_t), target, intent(inout) :: hm
726 type(grid_t), target, intent(in) :: gr
727 type(states_elec_t), target, intent(inout) :: st
728 type(propagator_base_t), target, intent(inout) :: tr
729 real(real64), intent(in) :: time
730 real(real64), intent(in) :: dt
731 type(ion_dynamics_t), intent(inout) :: ions_dyn
732 type(ions_t), intent(inout) :: ions
733 type(partner_list_t), target, intent(in) :: ext_partners
734
735 integer :: idim, ip, ist, ik, j, kp1, kp2, st1, st2, nspin
736 real(real64) :: dres
737 complex(real64), allocatable :: inhpsi(:)
738 complex(real64), allocatable :: zpsi(:), rhs(:)
739 complex(real64), allocatable :: zphi(:, :, :, :)
740 type(ion_state_t) :: ions_state
741
742 real(real64) :: a(2, 2), c(2), b(2)
743 complex(real64), allocatable :: k1(:, :, :, :), k2(:, :, :, :), oldk1(:, :, :, :), &
744 oldk2(:, :, :, :), yn1(:, :, :, :), yn2(:, :, :, :), &
745 rhs1(:, :, :, :), rhs2(:, :, :, :)
746
747 push_sub(td_runge_kutta4)
748
749 c(1) = m_half - sqrt(m_three)/6.0_real64
750 c(2) = m_half + sqrt(m_three)/6.0_real64
751 b(1) = m_half
752 b(2) = m_half
753 a(1, 1) = m_fourth
754 a(1, 2) = m_fourth - sqrt(m_three)/6.0_real64
755 a(2, 1) = m_fourth + sqrt(m_three)/6.0_real64
756 a(2, 2) = m_fourth
757
758 st1 = st%st_start
759 st2 = st%st_end
760 kp1 = st%d%kpt%start
761 kp2 = st%d%kpt%end
762 nspin = hm%d%nspin
763 move_ions_op = ion_dynamics_ions_move(ions_dyn)
764
765 sp_np = gr%np
766 sp_dim = st%d%dim
767 sp_st1 = st1
768 sp_st2 = st2
769 sp_kp1 = kp1
770 sp_kp2 = kp2
771 sp_parallel = st%parallel_in_states .or. st%d%kpt%parallel
772 if (sp_parallel) call mpi_grp_copy(sp_grp, st%st_kpt_mpi_grp)
773
774 ! define pointer and variables for usage in td_rk4op, td_rk4opt routines
775 mesh_p => gr
776 hm_p => hm
777 tr_p => tr
778 st_p => st
779 namespace_p => namespace
780 space_p => space
781 ext_partners_p => ext_partners
782 dt_op = dt
783 t_op = time - dt/m_two
784 dim_op = st%d%dim
785
786 safe_allocate(vpsl1_op(1:gr%np))
787 safe_allocate(vpsl2_op(1:gr%np))
788 safe_allocate(k1(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
789 safe_allocate(k2(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
790 safe_allocate(oldk1(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
791 safe_allocate(oldk2(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
792 safe_allocate(yn1(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
793 safe_allocate(yn2(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
794 safe_allocate(rhs1(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
795 safe_allocate(rhs2(1:gr%np_part, 1:st%d%dim, st1:st2, kp1:kp2))
796 safe_allocate(rhs(1:tr%tdsk_size))
797 safe_allocate(zpsi(1:tr%tdsk_size))
798 safe_allocate(zphi(1:gr%np_part, st%d%dim, st1:st2, kp1:kp2))
799
800 ! First, we get the state that we want to propagate. For the moment being, only one state.
801 do ik = kp1, kp2
802 do ist = st1, st2
803 call states_elec_get_state(st, gr, ist, ik, zphi(:, :, ist, ik))
804 end do
805 end do
806 k1 = m_z0
807 k2 = m_z0
808
809 do
810
811 oldk1 = k1
812 oldk2 = k2
813
814 yn1 = zphi + a(1, 1) * k1 + a(1, 2) * k2
815 yn2 = zphi + a(2, 1) * k1 + a(2, 2) * k2
816
817 ! Set the Hamiltonian at time-dt + c(1) * dt
818 do ik = kp1, kp2
819 do ist = st1, st2
820 call states_elec_set_state(st, gr, ist, ik, yn1(:, :, ist, ik))
821 end do
822 end do
823 call density_calc(st, gr, st%rho)
824 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
825 calc_current = list_has_gauge_field(ext_partners), &
826 calc_energy = .false., calc_eigenval = .false.)
827 if (ion_dynamics_ions_move(ions_dyn)) then
828 call ion_dynamics_save_state(ions_dyn, ions, ions_state)
829 call ion_dynamics_propagate(ions_dyn, ions, time - dt + c(1)*dt, c(1)*dt, namespace)
830 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = time - dt + c(1)*dt)
831 vpsl1_op = hm%ep%vpsl
832 end if
833
834 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time - dt + c(1)*dt)
835
836 call hm%ks_pot%store_potentials(vhxc1_op)
837 t_op = time - dt + c(1) * dt
838 rhs1 = m_z0
839 do ik = kp1, kp2
840 do ist = st1, st2
841 call zhamiltonian_elec_apply_single(hm_p, namespace, mesh_p, zphi(:, :, ist, ik), rhs1(:, :, ist, ik), ist, ik)
842 if (hamiltonian_elec_inh_term(hm)) then
843 safe_allocate(inhpsi(1:gr%np))
844 do idim = 1, st%d%dim
845 call states_elec_get_state(hm%inh_st, gr, idim, ist, ik, inhpsi)
846 do ip = 1, gr%np
847 rhs1(ip, idim, ist, ik) = rhs1(ip, idim, ist, ik) + m_zi * inhpsi(ip)
848 end do
849 end do
850 safe_deallocate_a(inhpsi)
851 end if
852 end do
853 end do
854 rhs1 = - m_zi * dt * rhs1
855 if (ion_dynamics_ions_move(ions_dyn)) then
856 call ion_dynamics_restore_state(ions_dyn, ions, ions_state)
857 end if
858
859 ! Set the Hamiltonian at time-dt + c(2) * dt
860 do ik = kp1, kp2
861 do ist = st1, st2
862 call states_elec_set_state(st, gr, ist, ik, yn2(:, :, ist, ik))
863 end do
864 end do
865 call density_calc(st, gr, st%rho)
866 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
867 calc_current = list_has_gauge_field(ext_partners), &
868 calc_energy = .false., calc_eigenval = .false.)
869 if (ion_dynamics_ions_move(ions_dyn)) then
870 call ion_dynamics_save_state(ions_dyn, ions, ions_state)
871 call ion_dynamics_propagate(ions_dyn, ions, time - dt + c(2)*dt, c(2)*dt, namespace)
872 call hamiltonian_elec_epot_generate(hm, namespace, space, gr, ions, ext_partners, st, time = time - dt + c(2)*dt)
873 vpsl2_op = hm%ep%vpsl
874 end if
875
876 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time - dt + c(2)*dt)
877
878 call hm%ks_pot%store_potentials(vhxc2_op)
879 t_op = time - dt + c(2) * dt
880 rhs2 = m_z0
881 do ik = kp1, kp2
882 do ist = st1, st2
883 call zhamiltonian_elec_apply_single(hm_p, namespace, mesh_p, zphi(:, :, ist, ik), rhs2(:, :, ist, ik), ist, ik)
884 if (hamiltonian_elec_inh_term(hm)) then
885 safe_allocate(inhpsi(1:gr%np))
886 do idim = 1, st%d%dim
887 call states_elec_get_state(hm%inh_st, gr, idim, ist, ik, inhpsi)
888 do ip = 1, gr%np
889 rhs2(ip, idim, ist, ik) = rhs2(ip, idim, ist, ik) + m_zi * inhpsi(ip)
890 end do
891 end do
892 safe_deallocate_a(inhpsi)
893 end if
894 end do
895 end do
896 rhs2 = -m_zi * dt * rhs2
897 if (ion_dynamics_ions_move(ions_dyn)) then
898 call ion_dynamics_restore_state(ions_dyn, ions, ions_state)
899 end if
900
901 j = 1
902 do ik = kp1, kp2
903 do ist = st1, st2
904 do idim = 1, st%d%dim
905 call lalg_copy(gr%np, rhs1(1:gr%np, idim, ist, ik), rhs(j:j+gr%np-1))
906 j = j + gr%np
907 end do
908 end do
909 end do
910 do ik = kp1, kp2
911 do ist = st1, st2
912 do idim = 1, st%d%dim
913 call lalg_copy(gr%np, rhs2(1:gr%np, idim, ist, ik), rhs(j:j+gr%np-1))
914 j = j + gr%np
915 end do
916 end do
917 end do
918
919 ! Now we populate an initial guess for the equation.
920 j = 1
921 do ik = kp1, kp2
922 do ist = st1, st2
923 do idim = 1, st%d%dim
924 call lalg_copy(gr%np, k1(1:gr%np, idim, ist, ik), zpsi(j:j+gr%np-1))
925 j = j + gr%np
926 end do
927 end do
928 end do
929 do ik = kp1, kp2
930 do ist = st1, st2
931 do idim = 1, st%d%dim
932 call lalg_copy(gr%np, k2(1:gr%np, idim, ist, ik), zpsi(j:j+gr%np-1))
933 j = j + gr%np
934 end do
935 end do
936 end do
937
938 t_op = time - dt
939 call zsparskit_solver_run(namespace, tr%tdsk, td_rk4op, td_rk4opt, zpsi, rhs)
940
941 k1 = m_z0
942 k2 = m_z0
943 j = 1
944 do ik = kp1, kp2
945 do ist = st1, st2
946 do idim = 1, st%d%dim
947 call lalg_copy(gr%np, zpsi(j:j+gr%np-1), k1(1:gr%np, idim, ist, ik))
948 j = j + gr%np
949 end do
950 end do
951 end do
952 do ik = kp1, kp2
953 do ist = st1, st2
954 do idim = 1, st%d%dim
955 call lalg_copy(gr%np, zpsi(j:j+gr%np-1), k2(1:gr%np, idim, ist, ik))
956 j = j + gr%np
957 end do
958 end do
959 end do
960
961 dres = m_zero
962 do ik = kp1, kp2
963 do ist = st1, st2
964 do idim = 1, st%d%dim
965 dres = dres + (zmf_nrm2(gr, k1(:, idim, ist, ik) - oldk1(:, idim, ist, ik)))**2
966 dres = dres + (zmf_nrm2(gr, k2(:, idim, ist, ik) - oldk2(:, idim, ist, ik)))**2
967 end do
968 end do
969 end do
970 if (sp_parallel) call comm_allreduce(sp_grp, dres)
971 !write(*, *) 'Residual = ', dres
972
973 if (sqrt(dres) < tr%scf_threshold) exit
974 end do
975
976
977 zphi = zphi + b(1) * k1 + b(2) * k2
978 do ik = kp1, kp2
979 do ist = st1, st2
980 call states_elec_set_state(st, gr, ist, ik, zphi(:, :, ist, ik))
981 end do
982 end do
983
984 call density_calc(st, gr, st%rho)
985
986 safe_deallocate_a(rhs1)
987 safe_deallocate_a(rhs2)
988 safe_deallocate_a(k1)
989 safe_deallocate_a(k2)
990 safe_deallocate_a(oldk1)
991 safe_deallocate_a(oldk2)
992 safe_deallocate_a(yn1)
993 safe_deallocate_a(yn2)
994 safe_deallocate_a(vpsl1_op)
995 safe_deallocate_a(vpsl2_op)
996 safe_deallocate_a(zpsi)
997 safe_deallocate_a(rhs)
998
999 pop_sub(td_runge_kutta4)
1000 end subroutine td_runge_kutta4
1001
1002 ! ---------------------------------------------------------
1004 subroutine td_rk4op(xre, xim, yre, yim)
1005 real(real64), intent(in) :: xre(:)
1006 real(real64), intent(in) :: xim(:)
1007 real(real64), intent(out) :: yre(:)
1008 real(real64), intent(out) :: yim(:)
1009
1010 integer :: idim, j, ik, ist, kp1, kp2, st1, st2, dim, k, jj
1011 complex(real64), allocatable :: zpsi(:, :)
1012 complex(real64), allocatable :: opzpsi(:, :)
1013 real(real64) :: a(2, 2), c(2)
1014 integer :: np_part, np
1015
1016 push_sub(td_rk4op)
1017
1018 np_part = mesh_p%np_part
1019 np = mesh_p%np
1020 st1 = st_p%st_start
1021 st2 = st_p%st_end
1022 kp1 = st_p%d%kpt%start
1023 kp2 = st_p%d%kpt%end
1024 dim = st_p%d%dim
1025
1026 safe_allocate(zpsi(1:np_part, 1:dim))
1027 safe_allocate(opzpsi(1:np_part, 1:dim))
1028
1029 a(1, 1) = m_fourth
1030 a(1, 2) = m_fourth - sqrt(m_three)/6.0_real64
1031 a(2, 1) = m_fourth + sqrt(m_three)/6.0_real64
1032 a(2, 2) = m_fourth
1033
1034 c(1) = m_half - sqrt(m_three)/6.0_real64
1035 c(2) = m_half + sqrt(m_three)/6.0_real64
1036
1037 zpsi = m_z0
1038
1039 call hm_p%ks_pot%restore_potentials(vhxc1_op)
1040 if (move_ions_op) hm_p%ep%vpsl = vpsl1_op
1041 call propagation_ops_elec_update_hamiltonian(namespace_p, space_p, st_p, mesh_p, hm_p, ext_partners_p, t_op + c(1)*dt_op)
1042 j = 1
1043 k = np * (kp2 - kp1 + 1) * (st2 - st1 + 1) * dim + 1
1044 do ik = kp1, kp2
1045 do ist = st1, st2
1046 jj = j
1047 do idim = 1, dim
1048 zpsi(1:np, idim) = a(1, 1) * cmplx(xre(j:j+np-1), xim(j:j+np-1), real64) + &
1049 a(1, 2) * cmplx(xre(k:k+np-1), xim(k:k+np-1), real64)
1050 j = j + np
1051 k = k + np
1052 end do
1053
1054 call zhamiltonian_elec_apply_single(hm_p, namespace_p, mesh_p, zpsi, opzpsi, ist, ik)
1055
1056 do idim = 1, dim
1057 yre(jj:jj+np-1) = xre(jj:jj+np-1) - aimag(dt_op * opzpsi(1:np, idim))
1058 yim(jj:jj+np-1) = xim(jj:jj+np-1) + real(dt_op * opzpsi(1:np, idim), real64)
1059 jj = jj + np
1060 end do
1061 end do
1062 end do
1063
1064 call hm_p%ks_pot%restore_potentials(vhxc2_op)
1065
1066 if (move_ions_op) hm_p%ep%vpsl = vpsl2_op
1067 call propagation_ops_elec_update_hamiltonian(namespace_p, space_p, st_p, mesh_p, hm_p, ext_partners_p, t_op + c(2)*dt_op)
1068 j = 1
1069 k = np * (kp2 - kp1 + 1) * (st2 - st1 + 1) * dim + 1
1070 do ik = kp1, kp2
1071 do ist = st1, st2
1072 jj = k
1073 do idim = 1, dim
1074 zpsi(1:np, idim) = a(2, 1) * cmplx(xre(j:j+np-1), xim(j:j+np-1), real64) + &
1075 a(2, 2) * cmplx(xre(k:k+np-1), xim(k:k+np-1), real64)
1076 j = j + np
1077 k = k + np
1078 end do
1079
1080 call zhamiltonian_elec_apply_single(hm_p, namespace_p, mesh_p, zpsi, opzpsi, ist, ik)
1081
1082 do idim = 1, dim
1083 yre(jj:jj+np-1) = xre(jj:jj+np-1) - aimag(dt_op * opzpsi(1:np, idim))
1084 yim(jj:jj+np-1) = xim(jj:jj+np-1) + real(dt_op * opzpsi(1:np, idim), real64)
1085 jj = jj + np
1086 end do
1087 end do
1088 end do
1089
1090 safe_deallocate_a(zpsi)
1091 safe_deallocate_a(opzpsi)
1092 pop_sub(td_rk4op)
1093 end subroutine td_rk4op
1094 ! ---------------------------------------------------------
1095
1096
1097 ! ---------------------------------------------------------
1099 subroutine td_rk4opt(xre, xim, yre, yim)
1100 real(real64), intent(in) :: xre(:)
1101 real(real64), intent(in) :: xim(:)
1102 real(real64), intent(out) :: yre(:)
1103 real(real64), intent(out) :: yim(:)
1104
1105 integer :: idim, j, ik, ist, kp1, kp2, st1, st2, dim, k, jj
1106 complex(real64), allocatable :: zpsi(:, :)
1107 complex(real64), allocatable :: opzpsi(:, :)
1108 real(real64) :: a(2, 2), c(2)
1109 integer :: np_part, np
1110
1111 push_sub(td_rk4opt)
1112
1113 np_part = mesh_p%np_part
1114 np = mesh_p%np
1115 st1 = st_p%st_start
1116 st2 = st_p%st_end
1117 kp1 = st_p%d%kpt%start
1118 kp2 = st_p%d%kpt%end
1119 dim = st_p%d%dim
1120
1121 safe_allocate(zpsi(1:np_part, 1:dim))
1122 safe_allocate(opzpsi(1:np_part, 1:dim))
1123
1124 a(1, 1) = m_fourth
1125 a(1, 2) = m_fourth - sqrt(m_three)/6.0_real64
1126 a(2, 1) = m_fourth + sqrt(m_three)/6.0_real64
1127 a(2, 2) = m_fourth
1128
1129 c(1) = m_half - sqrt(m_three)/6.0_real64
1130 c(2) = m_half + sqrt(m_three)/6.0_real64
1131
1132 zpsi = m_z0
1133
1134 call hm_p%ks_pot%restore_potentials(vhxc1_op)
1135 if (move_ions_op) hm_p%ep%vpsl = vpsl1_op
1136
1137 call propagation_ops_elec_update_hamiltonian(namespace_p, space_p, st_p, mesh_p, hm_p, ext_partners_p, t_op + c(1)*dt_op)
1138
1139 j = 1
1140 k = np * (kp2 - kp1 + 1) * (st2 - st1 + 1) * dim + 1
1141 do ik = kp1, kp2
1142 do ist = st1, st2
1143 jj = j
1144 do idim = 1, dim
1145 zpsi(1:np, idim) = a(1, 1) * cmplx(xre(j:j+np-1), -xim(j:j+np-1), real64) + &
1146 a(1, 2) * cmplx(xre(k:k+np-1), -xim(k:k+np-1), real64)
1147 j = j + np
1148 k = k + np
1149 end do
1150
1151 call zhamiltonian_elec_apply_single(hm_p, namespace_p, mesh_p, zpsi, opzpsi, ist, ik)
1152
1153 do idim = 1, dim
1154 yre(jj:jj+np-1) = xre(jj:jj+np-1) - aimag(dt_op * opzpsi(1:np, idim))
1155 yim(jj:jj+np-1) = xim(jj:jj+np-1) - real(dt_op * opzpsi(1:np, idim), real64)
1156 jj = jj + np
1157 end do
1158 end do
1159 end do
1160
1161 call hm_p%ks_pot%restore_potentials(vhxc2_op)
1162 if (move_ions_op) hm_p%ep%vpsl = vpsl2_op
1163
1164 call propagation_ops_elec_update_hamiltonian(namespace_p, space_p, st_p, mesh_p, hm_p, ext_partners_p, t_op + c(2)*dt_op)
1165
1166 j = 1
1167 k = np * (kp2 - kp1 + 1) * (st2 - st1 + 1) * dim + 1
1168 do ik = kp1, kp2
1169 do ist = st1, st2
1170 jj = k
1171 do idim = 1, dim
1172 zpsi(1:np, idim) = a(2, 1) * cmplx(xre(j:j+np-1), -xim(j:j+np-1), real64) + &
1173 a(2, 2) * cmplx(xre(k:k+np-1), -xim(k:k+np-1), real64)
1174 j = j + np
1175 k = k + np
1176 end do
1177
1178 call zhamiltonian_elec_apply_single(hm_p, namespace_p, mesh_p, zpsi, opzpsi, ist, ik)
1179
1180 do idim = 1, dim
1181 yre(jj:jj+np-1) = xre(jj:jj+np-1) - aimag(dt_op * opzpsi(1:np, idim))
1182 yim(jj:jj+np-1) = xim(jj:jj+np-1) - real(dt_op * opzpsi(1:np, idim), real64)
1183 jj = jj + np
1184 end do
1185 end do
1186 end do
1187
1188 safe_deallocate_a(zpsi)
1189 safe_deallocate_a(opzpsi)
1190 pop_sub(td_rk4opt)
1191 end subroutine td_rk4opt
1192 ! ---------------------------------------------------------
1193
1194
1195 ! ---------------------------------------------------------
1197 subroutine td_rk2op(xre, xim, yre, yim)
1198 real(real64), intent(in) :: xre(:)
1199 real(real64), intent(in) :: xim(:)
1200 real(real64), intent(out) :: yre(:)
1201 real(real64), intent(out) :: yim(:)
1202
1203 integer :: np_part, np, st1, st2, kp1, kp2, dim, idim, ik, ist, jj, j
1204 complex(real64), allocatable :: zpsi(:, :)
1205 complex(real64), allocatable :: opzpsi(:, :)
1206 complex(real64), allocatable :: zpsi_(:, :, :, :)
1207
1208 push_sub(td_rk2op)
1209
1210 np_part = mesh_p%np_part
1211 np = mesh_p%np
1212 st1 = st_p%st_start
1213 st2 = st_p%st_end
1214 kp1 = st_p%d%kpt%start
1215 kp2 = st_p%d%kpt%end
1216 dim = st_p%d%dim
1217
1218 safe_allocate(zpsi(1:np_part, 1:dim))
1219 safe_allocate(opzpsi(1:np_part, 1:dim))
1220 safe_allocate(zpsi_(1:np_part, 1:dim, st1:st2, kp1:kp2))
1221
1222 zpsi = m_z0
1223 opzpsi = m_z0
1224
1225 call hm_p%ks_pot%restore_potentials(vhxc1_op)
1226 if (move_ions_op) hm_p%ep%vpsl = vpsl1_op
1227 call propagation_ops_elec_update_hamiltonian(namespace_p, space_p, st_p, mesh_p, hm_p, ext_partners_p, t_op + dt_op)
1228
1229 if (oct_exchange_enabled(hm_p%oct_exchange)) then
1230 zpsi_ = m_z0
1231 j = 1
1232 do ik = kp1, kp2
1233 do ist = st1, st2
1234 jj = j
1235 do idim = 1, dim
1236 zpsi_(1:np, idim, ist, ik) = cmplx(xre(j:j+np-1), xim(j:j+np-1), real64)
1237 j = j + np
1238 end do
1239 end do
1240 end do
1241 call oct_exchange_prepare(hm_p%oct_exchange, mesh_p, zpsi_, hm_p%xc, hm_p%psolver, namespace_p)
1242 end if
1243
1244 j = 1
1245 do ik = kp1, kp2
1246 do ist = st1, st2
1247 jj = j
1248 do idim = 1, dim
1249 zpsi(1:np, idim) = cmplx(xre(j:j+np-1), xim(j:j+np-1), real64)
1250 j = j + np
1251 end do
1252 call zhamiltonian_elec_apply_single(hm_p, namespace_p, mesh_p, zpsi, opzpsi, ist, ik)
1253 do idim = 1, dim
1254 yre(jj:jj+np-1) = xre(jj:jj+np-1) - aimag(dt_op * m_half * opzpsi(1:np, idim))
1255 yim(jj:jj+np-1) = xim(jj:jj+np-1) + real(dt_op * m_half * opzpsi(1:np, idim), real64)
1256 jj = jj + np
1257 end do
1258 end do
1259 end do
1260
1261 if (oct_exchange_enabled(hm_p%oct_exchange)) then
1262 j = 1
1263 do ik = kp1, kp2
1264 do ist = st1, st2
1265 jj = j
1266 do idim = 1, dim
1267 zpsi(1:np, idim) = cmplx(xre(j:j+np-1), xim(j:j+np-1), real64)
1268 j = j + np
1269 end do
1270 opzpsi = m_z0
1271 call oct_exchange_operator(hm_p%oct_exchange, namespace_p, mesh_p, opzpsi, ist, ik)
1272
1273 do idim = 1, dim
1274 yre(jj:jj+np-1) = yre(jj:jj+np-1) - aimag(dt_op * m_half * opzpsi(1:np, idim))
1275 yim(jj:jj+np-1) = yim(jj:jj+np-1) + real(dt_op * m_half * opzpsi(1:np, idim), real64)
1276 jj = jj + np
1277 end do
1278 end do
1279 end do
1280 end if
1281
1282 safe_deallocate_a(zpsi)
1283 safe_deallocate_a(opzpsi)
1284
1285 pop_sub(td_rk2op)
1286 end subroutine td_rk2op
1287 ! ---------------------------------------------------------
1288
1289
1290 ! ---------------------------------------------------------
1292 subroutine td_rk2opt(xre, xim, yre, yim)
1293 real(real64), intent(in) :: xre(:)
1294 real(real64), intent(in) :: xim(:)
1295 real(real64), intent(out) :: yre(:)
1296 real(real64), intent(out) :: yim(:)
1297
1298 integer :: np_part, np, st1, st2, kp1, kp2, dim, idim, ik, ist, jj, j
1299 complex(real64), allocatable :: zpsi(:, :)
1300 complex(real64), allocatable :: opzpsi(:, :)
1301 complex(real64), allocatable :: zpsi_(:, :, :, :)
1302
1303 push_sub(td_rk2opt)
1304
1305 np_part = mesh_p%np_part
1306 np = mesh_p%np
1307 st1 = st_p%st_start
1308 st2 = st_p%st_end
1309 kp1 = st_p%d%kpt%start
1310 kp2 = st_p%d%kpt%end
1311 dim = st_p%d%dim
1312
1313 safe_allocate(zpsi(1:np_part, 1:dim))
1314 safe_allocate(opzpsi(1:np_part, 1:dim))
1315 safe_allocate(zpsi_(1:np_part, 1:dim, st1:st2, kp1:kp2))
1316
1317 zpsi = m_z0
1318 opzpsi = m_z0
1319
1320 call hm_p%ks_pot%restore_potentials(vhxc1_op)
1321 if (move_ions_op) hm_p%ep%vpsl = vpsl1_op
1322 call propagation_ops_elec_update_hamiltonian(namespace_p, space_p, st_p, mesh_p, hm_p, ext_partners_p, t_op + dt_op)
1323
1324 if (oct_exchange_enabled(hm_p%oct_exchange)) then
1325 zpsi_ = m_z0
1326 j = 1
1327 do ik = kp1, kp2
1328 do ist = st1, st2
1329 jj = j
1330 do idim = 1, dim
1331 zpsi_(1:np, idim, ist, ik) = cmplx(xre(j:j+np-1), -xim(j:j+np-1), real64)
1332 j = j + np
1333 end do
1334 end do
1335 end do
1336 call oct_exchange_prepare(hm_p%oct_exchange, mesh_p, zpsi_, hm_p%xc, hm_p%psolver, namespace_p)
1337 end if
1338
1339 j = 1
1340 do ik = kp1, kp2
1341 do ist = st1, st2
1342 jj = j
1343 do idim = 1, dim
1344 zpsi(1:np, idim) = cmplx(xre(j:j+np-1), -xim(j:j+np-1), real64)
1345 j = j + np
1346 end do
1347 call zhamiltonian_elec_apply_single(hm_p, namespace_p, mesh_p, zpsi, opzpsi, ist, ik)
1348
1349 do idim = 1, dim
1350 yre(jj:jj+np-1) = xre(jj:jj+np-1) - aimag(dt_op * m_half * opzpsi(1:np, idim))
1351 yim(jj:jj+np-1) = xim(jj:jj+np-1) - real(dt_op * m_half * opzpsi(1:np, idim), real64)
1352 jj = jj + np
1353 end do
1354 end do
1355 end do
1356
1357 if (oct_exchange_enabled(hm_p%oct_exchange)) then
1358 j = 1
1359 do ik = kp1, kp2
1360 do ist = st1, st2
1361 jj = j
1362 do idim = 1, dim
1363 zpsi(1:np, idim) = cmplx(xre(j:j+np-1), xim(j:j+np-1), real64)
1364 j = j + np
1365 end do
1366 opzpsi = m_z0
1367 call oct_exchange_operator(hm_p%oct_exchange, namespace_p, mesh_p, opzpsi, ist, ik)
1368
1369 do idim = 1, dim
1370 yre(jj:jj+np-1) = yre(jj:jj+np-1) - aimag(dt_op * m_half * opzpsi(1:np, idim))
1371 yim(jj:jj+np-1) = yim(jj:jj+np-1) - real(dt_op * m_half * opzpsi(1:np, idim), real64)
1372 jj = jj + np
1373 end do
1374 end do
1375 end do
1376 end if
1377
1378 safe_deallocate_a(zpsi)
1379 safe_deallocate_a(opzpsi)
1380 pop_sub(td_rk2opt)
1381 end subroutine td_rk2opt
1382 ! ---------------------------------------------------------
1383
1384 subroutine propagator_rk_end()
1386
1387 call xc_copied_potentials_end(vhxc1_op)
1388 call xc_copied_potentials_end(vhxc2_op)
1389
1390 pop_sub(propagator_rk_end)
1391 end subroutine propagator_rk_end
1392end module propagator_rk_oct_m
1393
1394!! Local Variables:
1395!! mode: f90
1396!! coding: utf-8
1397!! End:
batchified version of the BLAS axpy routine:
Definition: batch_ops.F90:154
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:186
double sqrt(double __x) __attribute__((__nothrow__
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:609
logical function, public list_has_gauge_field(partners)
subroutine, public forces_costate_calculate(gr, namespace, ions, hm, psi, chi, ff, qq)
Definition: forces.F90:218
subroutine, public forces_calculate(gr, namespace, ions, hm, ext_partners, st, ks, vhxc_old, t, dt)
Definition: forces.F90:339
real(real64), parameter, public m_two
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
real(real64), parameter, public m_third
Definition: global.F90:195
real(real64), parameter, public m_fourth
Definition: global.F90:197
complex(real64), parameter, public m_z0
Definition: global.F90:198
complex(real64), parameter, public m_zi
Definition: global.F90:202
real(real64), parameter, public m_half
Definition: global.F90:194
real(real64), parameter, public m_one
Definition: global.F90:189
real(real64), parameter, public m_three
Definition: global.F90:191
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public hamiltonian_elec_set_inh(hm, st)
subroutine, public hamiltonian_elec_adjoint(hm)
subroutine, public zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
subroutine, public zhamiltonian_elec_apply_all(hm, namespace, mesh, st, hst)
subroutine, public hamiltonian_elec_remove_inh(hm)
pure logical function, public hamiltonian_elec_inh_term(hm)
subroutine, public hamiltonian_elec_not_adjoint(hm)
This module defines classes and functions for interaction partners.
subroutine, public ion_dynamics_restore_state(this, ions, state)
subroutine, public ion_dynamics_propagate(this, ions, time, dt, namespace)
subroutine, public ion_dynamics_save_state(this, ions, state)
logical pure function, public ion_dynamics_ions_move(this)
A module to handle KS potential, without the external potential.
integer, parameter, public independent_particles
subroutine, public xc_copied_potentials_end(this)
Finalizer for the copied potentials.
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, hm_base, phase, energy)
Definition: lda_u.F90:797
This module defines various routines, operating on mesh functions.
integer, public sp_st2
logical, public sp_parallel
integer, public sp_dim
integer, public sp_kp2
integer, public sp_kp1
type(mpi_grp_t), public sp_grp
integer, public sp_st1
integer, public sp_np
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine mpi_grp_copy(mpi_grp_out, mpi_grp_in)
Definition: mpi.F90:403
logical function, public oct_exchange_enabled(this)
subroutine, public oct_exchange_remove(this)
subroutine, public oct_exchange_set(this, st, mesh)
subroutine, public oct_exchange_operator(this, namespace, mesh, hpsi, ist, ik)
subroutine, public oct_exchange_prepare(this, mesh, psi, xc, psolver, namespace)
This module holds the "opt_control_state_t" datatype, which contains a quantum-classical state.
real(real64) function, dimension(:, :), pointer, public opt_control_point_p(ocs)
real(real64) function, dimension(:, :), pointer, public opt_control_point_q(ocs)
type(states_elec_t) function, pointer, public opt_control_point_qs(ocs)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
subroutine, public td_runge_kutta2(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
subroutine, public td_runge_kutta4(ks, namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners)
subroutine td_rk2op(xre, xim, yre, yim)
operator for the RK2 propagator
subroutine td_rk4op(xre, xim, yre, yim)
operators for Crank-Nicolson scheme
subroutine, public td_explicit_runge_kutta4(ks, namespace, space, hm, gr, st, time, dt, ions_dyn, ions, ext_partners, qcchi)
subroutine, public propagator_rk_end()
subroutine td_rk2opt(xre, xim, yre, yim)
operator for the RK2 propagator
subroutine td_rk4opt(xre, xim, yre, yim)
Transpose of H (called e.g. by bi-conjugate gradient solver)
subroutine, public zsparskit_solver_run(namespace, sk, op, opt, sol, rhs)
Definition: sparskit.F90:784
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:730
subroutine f_ions(tau)
subroutine f_psi(tau)
subroutine apply_inh()
subroutine f_chi(tau)
subroutine update_state(epsilon)
subroutine prepare_inh()
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:168
The states_elec_t class contains all electronic wave functions.