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