Octopus
propagator_etrs.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
22 use accel_oct_m
23 use batch_oct_m
25 use debug_oct_m
30 use grid_oct_m
32 use global_oct_m
37 use ions_oct_m
39 use lda_u_oct_m
41 use math_oct_m
46 use parser_oct_m
49 use space_oct_m
54 use types_oct_m
55 use v_ks_oct_m
58 use xc_oct_m
59
60 implicit none
61
62 private
63
64 public :: &
65 td_etrs, &
66 td_etrs_sc, &
67 td_aetrs, &
70
71contains
72
87 subroutine td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
88 ions_dyn, ions, mc)
89 type(v_ks_t), intent(inout) :: ks
90 type(namespace_t), intent(in) :: namespace
91 type(electron_space_t), intent(in) :: space
92 type(hamiltonian_elec_t), intent(inout) :: hm
93 type(partner_list_t), intent(in) :: ext_partners
94 type(grid_t), intent(inout) :: gr
95 type(states_elec_t), intent(inout) :: st
96 type(propagator_base_t), intent(inout) :: tr
97 real(real64), intent(in) :: time
98 real(real64), intent(in) :: dt
99 type(ion_dynamics_t), intent(inout) :: ions_dyn
100 type(ions_t), intent(inout) :: ions
101 type(multicomm_t), intent(inout) :: mc
102
103 push_sub(td_etrs)
104
105 if (hm%theory_level == independent_particles) then
106 call td_etrs_independent_particles(namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
107 ions_dyn, ions, mc)
108 else
109 call td_etrs_predictor(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
110 ions_dyn, ions, mc)
111 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
112 endif
113
114 pop_sub(td_etrs)
115
116 end subroutine td_etrs
117
118
120 subroutine td_etrs_independent_particles(namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
121 ions_dyn, ions, mc)
122 type(namespace_t), intent(in) :: namespace
123 type(electron_space_t), intent(in) :: space
124 type(hamiltonian_elec_t), intent(inout) :: hm
125 type(partner_list_t), intent(in) :: ext_partners
126 type(grid_t), intent(inout) :: gr
127 type(states_elec_t), intent(inout) :: st
128 type(propagator_base_t), intent(inout) :: tr
129 real(real64), intent(in) :: time
130 real(real64), intent(in) :: dt
131 type(ion_dynamics_t), intent(inout) :: ions_dyn
132 type(ions_t), intent(inout) :: ions
133 type(multicomm_t), intent(inout) :: mc
134
135 type(gauge_field_t), pointer :: gfield
136
138
139 assert(hm%theory_level == independent_particles)
140
141 call propagation_ops_elec_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
142
143 ! first move the ions to time t
144 call propagation_ops_elec_move_ions(tr%propagation_ops_elec, gr, hm, st, namespace, space, ions_dyn, ions, &
145 ext_partners, mc, time, dt)
146
147 gfield => list_get_gauge_field(ext_partners)
148 if(associated(gfield)) then
149 call propagation_ops_elec_propagate_gauge_field(tr%propagation_ops_elec, gfield, dt, time)
150 end if
151
152 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
153
154 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
155
157
158 end subroutine td_etrs_independent_particles
159
160
180 subroutine td_etrs_predictor(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
181 ions_dyn, ions, mc)
182 type(v_ks_t), intent(inout) :: ks
183 type(namespace_t), intent(in) :: namespace
184 type(electron_space_t), intent(in) :: space
185 type(hamiltonian_elec_t), intent(inout) :: hm
186 type(partner_list_t), intent(in) :: ext_partners
187 type(grid_t), intent(inout) :: gr
188 type(states_elec_t), intent(inout) :: st
189 type(propagator_base_t), intent(inout) :: tr
190 real(real64), intent(in) :: time
191 real(real64), intent(in) :: dt
192 type(ion_dynamics_t), intent(inout) :: ions_dyn
193 type(ions_t), intent(inout) :: ions
194 type(multicomm_t), intent(inout) :: mc
195
196 type(gauge_field_t), pointer :: gfield
197
198 push_sub(td_etrs_predictor)
199
200 if (v_ks_is_orbital_dependent(ks) .or. hm%lda_u_level /= dft_u_none) then
201 ! Full-step states, allocated once and reused every step.
202 ! With ACE, v_ks_calc leaves hm%exxop%st pointing at them.
203 if (.not. allocated(tr%st)) then
204 safe_allocate(tr%st)
205 call states_elec_copy(tr%st, st)
206 end if
207
208 ! st contains \psi_{n+1/2} = exp(-i dt/2 H_n) \psi_n
209 ! tr%st contains \tilde{\psi}_{n+1} = exp(-i dt H_n) psi_n
210 ! Predictor density from states propagated by the full time step, \tilde{\psi}_{n+1}
211 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt, dt, st_td=tr%st)
212
213 ! Compute potentials, V_{n+1}, from predictor density and states at dt
214 call v_ks_calc(ks, namespace, space, hm, tr%st, ions, ext_partners, &
215 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
216 else
217 ! st contains \psi_{n+1/2} = exp(-i dt/2 H_n) \psi_n
218 ! Predictor density from states propagated by the full time step, \tilde{\psi}_{n+1}
219 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt, dt)
220
221 ! Compute potentials, V_{n+1}, from predictor density at dt
222 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
223 calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
224 endif
225
226 ! Advance ions and gauge field to t_{n+1}. Neither reads the Hamiltonian. The ions use
227 ! forces from the end of the previous step, and epot_generate rebuilds the ionic terms
228 call propagation_ops_elec_move_ions(tr%propagation_ops_elec, gr, hm, st, namespace, space, ions_dyn, ions, &
229 ext_partners, mc, time, dt)
230
231 gfield => list_get_gauge_field(ext_partners)
232 if(associated(gfield)) then
233 call propagation_ops_elec_propagate_gauge_field(tr%propagation_ops_elec, gfield, dt, time)
234 end if
235
236 ! Assemble H_{n+1} from V_{n+1}, the moved ions and the new gauge field
237 if (v_ks_is_orbital_dependent(ks) .or. hm%lda_u_level /= dft_u_none) then
238 ! Maxwell and LDA+U require predictor density and states, respectively
239 call propagation_ops_elec_update_hamiltonian(namespace, space, tr%st, gr, hm, ext_partners, time)
240 else
241 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
242 endif
243
244 pop_sub(td_etrs_predictor)
245
246 end subroutine td_etrs_predictor
247
248
250 subroutine td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
251 ions_dyn, ions, mc, sctol, scsteps)
252 type(v_ks_t), intent(inout) :: ks
253 type(namespace_t), intent(in) :: namespace
254 type(electron_space_t), intent(in) :: space
255 type(hamiltonian_elec_t), intent(inout) :: hm
256 type(partner_list_t), intent(in) :: ext_partners
257 type(grid_t), intent(inout) :: gr
258 type(states_elec_t), intent(inout) :: st
259 type(propagator_base_t), intent(inout) :: tr
260 real(real64), intent(in) :: time
261 real(real64), intent(in) :: dt
262 type(ion_dynamics_t), intent(inout) :: ions_dyn
263 type(ions_t), intent(inout) :: ions
264 type(multicomm_t), intent(inout) :: mc
265 real(real64), intent(in) :: sctol
266 integer, optional, intent(out) :: scsteps
267
268 integer, parameter :: niter = 10
269 integer :: ik, ib, iter
270 logical :: orbital_dependent
271 real(real64) :: diff
272 class(wfs_elec_t), allocatable :: psi2(:, :)
273 type(xc_copied_potentials_t) :: vhxc_t2
274
275 push_sub(td_etrs_sc)
276
277 assert(hm%theory_level /= independent_particles)
278
279 call messages_new_line()
280 call messages_write(' Self-consistency iteration:')
281 call messages_info(namespace=namespace)
282
283 call td_etrs_predictor(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
284 ions_dyn, ions, mc)
285
286 ! Store the state at half iteration
287 safe_allocate_type_array(wfs_elec_t, psi2, (st%group%block_start:st%group%block_end, st%d%kpt%start:st%d%kpt%end))
288 do ik = st%d%kpt%start, st%d%kpt%end
289 do ib = st%group%block_start, st%group%block_end
290 call st%group%psib(ib, ik)%copy_to(psi2(ib, ik), copy_data=.true.)
291 end do
292 end do
293
294 orbital_dependent = v_ks_is_orbital_dependent(ks) .or. hm%lda_u_level /= dft_u_none
295
296 do iter = 1, niter
297 if (.not. orbital_dependent) call hm%ks_pot%store_potentials(vhxc_t2)
298
299 ! Predict the states and density at the full step, n+1
300 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half * dt)
301
302 if (orbital_dependent) then
303 ! Change of the full-step states since the previous iterate; tr%st holds the predictor at iter 1
304 diff = m_two * states_elec_calc_orbital_difference(gr, st, st%group%psib, tr%st%group%psib) / abs(dt)
305 write(message(1), '(a,i0,a,es9.2)') ' step ', iter, ', residue = ', abs(diff)
306 call messages_info(1, namespace=namespace)
307 if (abs(diff) <= sctol) exit
308 ! Keep this iterate as the reference for the next comparison
309 do ik = st%d%kpt%start, st%d%kpt%end
310 do ib = st%group%block_start, st%group%block_end
311 call st%group%psib(ib, ik)%copy_data_to(gr%np, tr%st%group%psib(ib, ik))
312 end do
313 end do
314 endif
315
316 ! Rebuild potentials and H at n+1
317 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
318 time = time, calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
319 call lda_u_update_occ_matrices(hm%lda_u, namespace, gr, st, hm%phase, hm%energy)
320
321 if (.not. orbital_dependent) then
322 ! Check how much the potential changed
323 diff = hm%ks_pot%check_convergence(vhxc_t2, gr, st%rho, st%qtot)
324 write(message(1), '(a,i0,a,es9.2)') ' step ', iter, ', residue = ', abs(diff)
325 call messages_info(1, namespace=namespace)
326 if (abs(diff) <= sctol) exit
327 endif
328
329 if (iter /= niter) then
330 ! we are not converged, restore the states at half iteration
331 do ik = st%d%kpt%start, st%d%kpt%end
332 do ib = st%group%block_start, st%group%block_end
333 call psi2(ib, ik)%copy_data_to(gr%np, st%group%psib(ib, ik))
334 end do
335 end do
336 end if
337 end do
338
339 if (hm%lda_u_level /= dft_u_none) then
340 call lda_u_write_u(hm%lda_u, namespace=namespace)
341 call lda_u_write_v(hm%lda_u, namespace=namespace)
342 end if
343
344 ! print an empty line
345 call messages_info(namespace=namespace)
346
347 if (present(scsteps)) scsteps = iter
348
349 do ik = st%d%kpt%start, st%d%kpt%end
350 do ib = st%group%block_start, st%group%block_end
351 call psi2(ib, ik)%end()
352 end do
353 end do
354
355 safe_deallocate_a(psi2)
356
357 pop_sub(td_etrs_sc)
358 end subroutine td_etrs_sc
359
361 subroutine td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
362 type(namespace_t), intent(in) :: namespace
363 type(electron_space_t), intent(in) :: space
364 type(hamiltonian_elec_t), intent(inout) :: hm
365 type(grid_t), intent(inout) :: gr
366 type(states_elec_t), intent(inout) :: st
367 type(propagator_base_t), intent(inout) :: tr
368 real(real64), intent(in) :: time
369 real(real64), intent(in) :: dt
370 type(ion_dynamics_t), intent(inout) :: ions_dyn
371 type(ions_t), intent(inout) :: ions
372 type(partner_list_t), intent(in) :: ext_partners
373 type(multicomm_t), intent(inout) :: mc
374
375 type(gauge_field_t), pointer :: gfield
376
377 push_sub(td_aetrs)
378
379 ! propagate half of the time step with H(time - dt)
380 call propagation_ops_elec_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
381
382 !Get the potentials from the interpolation
383 call propagation_ops_elec_interpolate_get(hm, tr%vks_old)
384
385 ! move the ions to time t
386 call propagation_ops_elec_move_ions(tr%propagation_ops_elec, gr, hm, st, namespace, space, ions_dyn, &
387 ions, ext_partners, mc, time, dt)
388
389 !Propagate gauge field
390 gfield => list_get_gauge_field(ext_partners)
391 if(associated(gfield)) then
392 call propagation_ops_elec_propagate_gauge_field(tr%propagation_ops_elec, gfield, dt, time)
393 end if
394
395 !Update Hamiltonian
396 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
397
398 !Do the time propagation for the second half of the time step
399 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
400
401 pop_sub(td_aetrs)
402 end subroutine td_aetrs
403
404 ! ---------------------------------------------------------
406 subroutine td_aetrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
407 ions_dyn, ions, mc, sctol, scsteps)
408 type(v_ks_t), intent(inout) :: ks
409 type(namespace_t), intent(in) :: namespace
410 type(electron_space_t), intent(in) :: space
411 type(hamiltonian_elec_t), intent(inout) :: hm
412 type(partner_list_t), intent(in) :: ext_partners
413 type(grid_t), intent(inout) :: gr
414 type(states_elec_t), intent(inout) :: st
415 type(propagator_base_t), intent(inout) :: tr
416 real(real64), intent(in) :: time
417 real(real64), intent(in) :: dt
418 type(ion_dynamics_t), intent(inout) :: ions_dyn
419 type(ions_t), intent(inout) :: ions
420 type(multicomm_t), intent(inout) :: mc
421 real(real64), intent(in) :: sctol
422 integer, optional, intent(out) :: scsteps
423
424 real(real64) :: diff
425 integer :: iter, ib, ik
426 type(states_elec_t) :: st0
427 integer, parameter :: niter = 10
428 logical :: orbital_dependent
429 type(gauge_field_t), pointer :: gfield
430 type(xc_copied_potentials_t) :: vhxc_t2
431
432 push_sub(td_aetrs_sc)
433
434 assert(hm%theory_level /= independent_particles)
435
436 call messages_new_line()
437 call messages_write(' Self-consistency iteration:')
438 call messages_info(namespace=namespace)
439
440 ! First half-step with H(t - dt)
441 call propagation_ops_elec_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
442
443 ! Initial guess for H(t) from extrapolated potentials
444 call propagation_ops_elec_interpolate_get(hm, tr%vks_old)
445
446 ! Move ions and gauge to t only once before SC loop
447 call propagation_ops_elec_move_ions(tr%propagation_ops_elec, gr, hm, st, namespace, space, ions_dyn, ions, &
448 ext_partners, mc, time, dt)
449
450 gfield => list_get_gauge_field(ext_partners)
451 if (associated(gfield)) then
452 call propagation_ops_elec_propagate_gauge_field(tr%propagation_ops_elec, gfield, dt, time)
453 end if
454
455 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
457 orbital_dependent = v_ks_is_orbital_dependent(ks) .or. hm%lda_u_level /= dft_u_none
458
459 ! Store the half-step state to restart each SC iteration
460 call states_elec_copy(st0, st)
461
462 ! Reference states for the orbital residue, constructed on the first
463 ! self-consistent step and reused for the rest of the run
464 if (orbital_dependent .and. .not. allocated(tr%st)) then
465 safe_allocate(tr%st)
466 call states_elec_copy(tr%st, st)
467 end if
468
469 diff = m_huge
470
471 do iter = 1, niter
472 if (.not. orbital_dependent) call hm%ks_pot%store_potentials(vhxc_t2)
473
474 call propagation_ops_elec_fuse_density_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
475
476 if (orbital_dependent) then
477 call messages_write(' step ')
478 call messages_write(iter)
479 ! Nothing to evaluate for the first step, as there is no extrapolation for wave functions
480 if (iter > 1) then
481 ! Change of the full-step states since the previous iteration
482 diff = m_two * states_elec_calc_orbital_difference(gr, st, st%group%psib, tr%st%group%psib) / abs(dt)
483 call messages_write(', residue = ')
484 call messages_write(abs(diff), fmt = '(1x,es9.2)')
485 endif
486 call messages_info(namespace=namespace)
487 if (abs(diff) <= sctol) exit
488 ! Keep this iterate as the reference for the next comparison
489 do ik = st%d%kpt%start, st%d%kpt%end
490 do ib = st%group%block_start, st%group%block_end
491 call st%group%psib(ib, ik)%copy_data_to(gr%np, tr%st%group%psib(ib, ik))
492 end do
493 end do
494 endif
495
496 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, &
497 time = time, calc_current = .false., calc_energy = .false., calc_eigenval = .false.)
498 call lda_u_update_occ_matrices(hm%lda_u, namespace, gr, st, hm%phase, hm%energy)
499
500 if (.not. orbital_dependent) then
501 diff = hm%ks_pot%check_convergence(vhxc_t2, gr, st%rho, st%qtot)
502 write(message(1), '(a,i0,a,es9.2)') ' step ', iter, ', residue = ', abs(diff)
503 call messages_info(1, namespace=namespace)
504 if (diff <= sctol) exit
505 endif
506
507 if (iter /= niter) then
508 ! restore initial states for next iteration
509 call states_elec_group_copy(st0%d, st0%group, st%group)
510 end if
511 end do
512
513 if (hm%lda_u_level /= dft_u_none) then
514 call lda_u_write_u(hm%lda_u, namespace=namespace)
515 call lda_u_write_v(hm%lda_u, namespace=namespace)
516 end if
517
518 call messages_info(namespace=namespace)
519
520 if (present(scsteps)) scsteps = iter
521
522 call states_elec_end(st0)
523
524 pop_sub(td_aetrs_sc)
525 end subroutine td_aetrs_sc
526
527 ! ---------------------------------------------------------
529 subroutine td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, &
530 ions_dyn, ions, mc)
531 type(v_ks_t), intent(inout) :: ks
532 type(namespace_t), intent(in) :: namespace
533 type(electron_space_t), intent(in) :: space
534 type(hamiltonian_elec_t), intent(inout) :: hm
535 type(partner_list_t), intent(in) :: ext_partners
536 type(grid_t), intent(inout) :: gr
537 type(states_elec_t), intent(inout) :: st
538 type(propagator_base_t), intent(inout) :: tr
539 real(real64), intent(in) :: time
540 real(real64), intent(in) :: dt
541 type(ion_dynamics_t), intent(inout) :: ions_dyn
542 type(ions_t), intent(inout) :: ions
543 type(multicomm_t), intent(inout) :: mc
544
545 integer :: ik, ispin, ip, ib
546 real(real64) :: vv
547 complex(real64), allocatable :: phase(:)
548 type(density_calc_t) :: dens_calc
549 integer(int64) :: pnp
550 integer(int64), dimension(3) :: gsizes, bsizes
551 type(accel_mem_t) :: phase_buff
552 type(gauge_field_t), pointer :: gfield
553 type(xc_copied_potentials_t) :: vold
554
555 push_sub(td_caetrs)
556
557 ! Get the interpolated KS potentials into vold
558 call hm%ks_pot%get_interpolated_potentials(tr%vks_old, 2, storage=vold)
559 ! And set it to the Hamiltonian
560 call hm%ks_pot%restore_potentials(vold)
561
562 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time - dt)
563
564 call v_ks_calc_start(ks, namespace, space, hm, st, ions, ions%latt, ext_partners, &
565 time = time - dt, calc_energy = .false.)
566
567 ! propagate half of the time step with H(time - dt)
568 call propagation_ops_elec_exp_apply(tr%te, namespace, st, gr, hm, m_half*dt)
569
570 call v_ks_calc_finish(ks, hm, namespace, space, ions%latt, st, ext_partners)
571
572 call hm%ks_pot%set_interpolated_potentials(tr%vks_old, 1)
573
574 call hm%ks_pot%perform_interpolation(tr%vks_old, (/time - dt, time - m_two*dt, time - m_three*dt/), time)
575
576 ! Replace vold by 0.5(vhxc+vold)
577 call hm%ks_pot%mix_potentials(vold, dt)
578
579 ! copy vold to a cl buffer
580 if (accel_is_enabled() .and. hm%apply_packed()) then
581 if (family_is_mgga_with_exc(hm%xc)) then
582 call messages_not_implemented('CAETRS propagator with accel and MGGA with energy functionals', namespace=namespace)
583 end if
584 pnp = accel_padded_size(gr%np)
585 call accel_create_buffer(phase_buff, accel_mem_read_only, type_float, pnp*st%d%nspin)
586 call vold%copy_vhxc_to_buffer(int(gr%np, int64), st%d%nspin, pnp, phase_buff)
587 end if
588
589 !Get the potentials from the interpolator
590 call propagation_ops_elec_interpolate_get(hm, tr%vks_old)
591
592 ! move the ions to time t
593 call propagation_ops_elec_move_ions(tr%propagation_ops_elec, gr, hm, st, namespace, space, ions_dyn, &
594 ions, ext_partners, mc, time, dt)
595
596 gfield => list_get_gauge_field(ext_partners)
597 if(associated(gfield)) then
598 call propagation_ops_elec_propagate_gauge_field(tr%propagation_ops_elec, gfield, dt, time)
599 end if
600
601 call propagation_ops_elec_update_hamiltonian(namespace, space, st, gr, hm, ext_partners, time)
602
603 call density_calc_init(dens_calc, st, gr, st%rho)
604
605 ! propagate the other half with H(t)
606 do ik = st%d%kpt%start, st%d%kpt%end
607 ispin = st%d%get_spin_index(ik)
608
609 do ib = st%group%block_start, st%group%block_end
610 if (hm%apply_packed()) then
611 call st%group%psib(ib, ik)%do_pack()
612 if (hamiltonian_elec_inh_term(hm)) call hm%inh_st%group%psib(ib, ik)%do_pack()
613 end if
614
615 call profiling_in("CAETRS_PHASE")
616 select case (st%group%psib(ib, ik)%status())
618 safe_allocate(phase(1:gr%np))
619 do ip = 1, gr%np
620 vv = vold%vhxc(ip, ispin)
621 phase(ip) = cmplx(cos(vv), -sin(vv), real64)
622 end do
623 call batch_mul_mf(gr%np, phase, st%group%psib(ib, ik), st%group%psib(ib, ik))
624 safe_deallocate_a(phase)
626 call accel_set_kernel_arg(kernel_phase, 0, pnp*(ispin - 1))
627 call accel_set_kernel_arg(kernel_phase, 1, gr%np)
628 call accel_set_kernel_arg(kernel_phase, 2, phase_buff)
629 call accel_set_kernel_arg(kernel_phase, 3, st%group%psib(ib, ik)%ff_device)
630 call accel_set_kernel_arg(kernel_phase, 4, log2(st%group%psib(ib, ik)%pack_size(1)))
631
632 ! Compute the grid (extend to another dimensions if the size of the problem is too big)
633 call accel_grid_size_extend_dim(pnp, st%group%psib(ib, ik)%pack_size(1), gsizes, bsizes)
634
635 call accel_kernel_run(kernel_phase, gsizes, bsizes)
636
637 end select
638 call profiling_out("CAETRS_PHASE")
639
640 call hm%phase%set_phase_corr(gr, st%group%psib(ib, ik))
641 if (hamiltonian_elec_inh_term(hm)) then
642 call tr%te%apply_batch(namespace, gr, hm, st%group%psib(ib, ik), m_half*dt, &
643 inh_psib = hm%inh_st%group%psib(ib, ik))
644 else
645 call tr%te%apply_batch(namespace, gr, hm, st%group%psib(ib, ik), m_half*dt)
646 end if
647 call hm%phase%unset_phase_corr(gr, st%group%psib(ib, ik))
648
649 call density_calc_accumulate(dens_calc, st%group%psib(ib, ik))
650
651 if (hm%apply_packed()) then
652 call st%group%psib(ib, ik)%do_unpack()
653 if (hamiltonian_elec_inh_term(hm)) call hm%inh_st%group%psib(ib, ik)%do_unpack()
654 end if
655 end do
656 end do
657
658 call density_calc_end(dens_calc)
659
660 if (accel_is_enabled() .and. hm%apply_packed()) then
661 call accel_free_buffer(phase_buff)
662 end if
663
664 pop_sub(td_caetrs)
665 end subroutine td_caetrs
666
667end module propagator_etrs_oct_m
668
669!! Local Variables:
670!! mode: f90
671!! coding: utf-8
672!! End:
batchified multiplication by mesh function with optional conjugation:
Definition: batch_ops.F90:269
double sin(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:990
type(accel_kernel_t), target, save, public kernel_phase
Definition: accel.F90:275
pure logical function, public accel_is_enabled()
Definition: accel.F90:414
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
This module implements batches of mesh functions.
Definition: batch.F90:135
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
Definition: batch.F90:311
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
Definition: batch.F90:311
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
Definition: batch.F90:311
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_accumulate(this, psib, async)
Accumulate weighted orbital densities for a batch psib.
Definition: density.F90:400
subroutine, public density_calc_init(this, st, gr, density)
initialize the density calculator
Definition: density.F90:191
subroutine, public density_calc_end(this, allreduce, symmetrize, buff_density)
Finalize the density calculation.
Definition: density.F90:570
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_huge
Definition: global.F90:218
integer, parameter, public independent_particles
Theory level.
Definition: global.F90:250
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_three
Definition: global.F90:203
This module implements the underlying real-space grid.
Definition: grid.F90:119
pure logical function, public hamiltonian_elec_inh_term(hm)
This module defines classes and functions for interaction partners.
A module to handle KS potential, without the external potential.
subroutine, public lda_u_write_u(this, iunit, namespace)
Definition: lda_u_io.F90:527
subroutine, public lda_u_write_v(this, iunit, namespace)
Definition: lda_u_io.F90:575
integer, parameter, public dft_u_none
Definition: lda_u.F90:205
subroutine, public lda_u_update_occ_matrices(this, namespace, mesh, st, phase, energy)
Definition: lda_u.F90:894
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines various routines, operating on mesh functions.
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
subroutine, public messages_new_line()
Definition: messages.F90:1089
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:668
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:600
subroutine, public propagation_ops_elec_propagate_gauge_field(wo, gfield, dt, time, save_gf)
subroutine, public propagation_ops_elec_update_hamiltonian(namespace, space, st, mesh, hm, ext_partners, time)
subroutine, public propagation_ops_elec_fuse_density_exp_apply(te, namespace, st, gr, hm, dt, dt2, op, st_td)
Apply to all states, and accumulate the density in the same pass.
subroutine, public propagation_ops_elec_interpolate_get(hm, vks_old)
subroutine, public propagation_ops_elec_move_ions(wo, gr, hm, st, namespace, space, ions_dyn, ions, ext_partners, mc, time, dt, save_pos)
subroutine, public propagation_ops_elec_exp_apply(te, namespace, st, mesh, hm, dt, op)
subroutine, public td_aetrs(namespace, space, hm, gr, st, tr, time, dt, ions_dyn, ions, ext_partners, mc)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public td_etrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc, sctol, scsteps)
Propagator with enforced time-reversal symmetry and self-consistency.
subroutine td_etrs_predictor(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
ETRS predictor step.
subroutine, public td_etrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with enforced time-reversal symmetry, ETRS.
subroutine td_etrs_independent_particles(namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with enforced time-reversal symmetry for independent particles.
subroutine, public td_caetrs(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc)
Propagator with approximate enforced time-reversal symmetry.
subroutine, public td_aetrs_sc(ks, namespace, space, hm, ext_partners, gr, st, tr, time, dt, ions_dyn, ions, mc, sctol, scsteps)
Propagator with approximate enforced time-reversal symmetry and self-consistency.
real(real64) function, public states_elec_calc_orbital_difference(mesh, st, psib1, psib2)
Compute the occupation- and k-point-weighted RMS difference between two sets of orbitals.
This module handles spin dimensions of the states and the k-point distribution.
This module handles groups of electronic batches and their parallel distribution.
subroutine, public states_elec_group_copy(d, group_in, group_out, copy_data, special, dest_type)
make a copy of a group
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special, dest_type, copy_data)
make a (selective) copy of a states_elec_t object
type(type_t), parameter, public type_float
Definition: types.F90:136
subroutine, public v_ks_calc_finish(ks, hm, namespace, space, latt, st, ext_partners, force_semilocal)
Definition: v_ks.F90:1091
logical function, public v_ks_is_orbital_dependent(ks)
Is the theory method and functional orbital-dependent?
Definition: v_ks.F90:1514
subroutine, public v_ks_calc_start(ks, namespace, space, hm, st, ions, latt, ext_partners, time, calc_energy, force_semilocal)
This routine starts the calculation of the Kohn-Sham potential. The routine v_ks_calc_finish must be ...
Definition: v_ks.F90:775
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:720
Definition: xc.F90:120
logical pure function, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
Definition: xc.F90:729
The calculator object.
Definition: density.F90:172
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
Stores all communicators and groups.
Definition: multicomm.F90:208
The states_elec_t class contains all electronic wave functions.
batches of electronic states
Definition: wfs_elec.F90:143
int true(void)