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