Octopus
hamiltonian_elec.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2020 M. Marques, A. Castro, A. Rubio, G. Bertsch,
2!! N. Tancogne-Dejean, M. Lueders
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
24 use accel_oct_m
26 use batch_oct_m
29 use comm_oct_m
30 use debug_oct_m
33 use energy_oct_m
38 use epot_oct_m
41 use global_oct_m
42 use grid_oct_m
46 use io_oct_m
47 use ions_oct_m
48 use kick_oct_m
49 use, intrinsic :: iso_fortran_env
52 use lasers_oct_m
54 use lda_u_oct_m
57 use math_oct_m
58 use mesh_oct_m
61 use mpi_oct_m
65 use nlcc_oct_m
68 use parser_oct_m
73 use pcm_oct_m
74 use phase_oct_m
77 use space_oct_m
85 use types_oct_m
86 use unit_oct_m
90 use xc_oct_m
91 use xc_f03_lib_m
95 use zora_oct_m
96
97 implicit none
98
99 private
100 public :: &
111 magnus, &
112 dvmask, &
113 zvmask, &
131
132
133 type, extends(hamiltonian_abst_t) :: hamiltonian_elec_t
134 ! Components are public by default
135
138 type(space_t), private :: space
139 type(states_elec_dim_t) :: d
140 type(hamiltonian_elec_base_t) :: hm_base
141 type(phase_t) :: phase
142 type(energy_t), allocatable :: energy
143 type(absorbing_boundaries_t) :: abs_boundaries
144 real(real64), allocatable :: vhartree(:)
145 real(real64), allocatable :: vxc(:,:)
146 real(real64), allocatable :: vhxc(:,:)
147 real(real64), allocatable :: vtau(:,:)
148 real(real64), allocatable :: vberry(:,:)
149
150 type(derivatives_t), pointer, private :: der
151
152 type(nonlocal_pseudopotential_t) :: vnl
153
154 type(ions_t), pointer :: ions
155 real(real64) :: exx_coef
156
157 type(poisson_t) :: psolver
158
160 logical :: self_induced_magnetic
161 real(real64), allocatable :: a_ind(:, :)
162 real(real64), allocatable :: b_ind(:, :)
163
164 integer :: theory_level
165 type(xc_t), pointer :: xc
166 type(xc_photons_t), pointer :: xc_photons
167
168 type(epot_t) :: ep
169 type(pcm_t) :: pcm
170
172 logical, private :: adjoint
173
175 real(real64), private :: mass
176
178 logical, private :: inh_term
179 type(states_elec_t) :: inh_st
180
183 type(oct_exchange_t) :: oct_exchange
184
185 type(scissor_t) :: scissor
186
187 real(real64) :: current_time
188 logical, private :: is_applied_packed
189
191 type(lda_u_t) :: lda_u
192 integer :: lda_u_level
193
194 logical, public :: time_zero
195
196 type(exchange_operator_t), public :: exxop
197
198 type(kpoints_t), pointer, public :: kpoints => null()
199
200 type(partner_list_t) :: external_potentials
201 real(real64), allocatable, public :: v_ext_pot(:)
202 real(real64), allocatable, public :: v_static(:)
203
204 type(ion_electron_local_potential_t) :: v_ie_loc
205 type(nlcc_t) :: nlcc
206
207 type(magnetic_constrain_t) :: magnetic_constrain
208
210 type(kick_t) :: kick
211
213 type(mxll_coupling_t) :: mxll
214 type(zora_t), pointer :: zora
215
216 contains
217 procedure :: update => hamiltonian_elec_update
218 procedure :: apply_packed => hamiltonian_elec_apply_packed
219 procedure :: update_span => hamiltonian_elec_span
220 procedure :: dapply => dhamiltonian_elec_apply
221 procedure :: zapply => zhamiltonian_elec_apply
222 procedure :: dmagnus_apply => dhamiltonian_elec_magnus_apply
223 procedure :: zmagnus_apply => zhamiltonian_elec_magnus_apply
224 procedure :: is_hermitian => hamiltonian_elec_hermitian
225 procedure :: set_mass => hamiltonian_elec_set_mass
227
228 integer, public, parameter :: &
229 LENGTH = 1, &
230 velocity = 2
232 integer, public, parameter :: &
234 hartree = 1, &
241contains
242
243 ! ---------------------------------------------------------
244 subroutine hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, &
245 mc, kpoints, need_exchange, xc_photons)
246 type(hamiltonian_elec_t), target, intent(inout) :: hm
247 type(namespace_t), intent(in) :: namespace
248 class(space_t), intent(in) :: space
249 type(grid_t), target, intent(inout) :: gr
250 type(ions_t), target, intent(inout) :: ions
251 type(partner_list_t), intent(inout) :: ext_partners
252 type(states_elec_t), target, intent(inout) :: st
253 integer, intent(in) :: theory_level
254 type(xc_t), target, intent(in) :: xc
255 type(multicomm_t), intent(in) :: mc
256 type(kpoints_t), target, intent(in) :: kpoints
257 logical, optional, intent(in) :: need_exchange
258 type(xc_photons_t), optional, target, intent(in) :: xc_photons
260
261 logical :: need_exchange_
262 real(real64) :: rashba_coupling
263
264 push_sub(hamiltonian_elec_init)
265 call profiling_in('HAMILTONIAN_ELEC_INIT')
266
267 ! make a couple of local copies
268 hm%space = space
269 hm%theory_level = theory_level
270 call states_elec_dim_copy(hm%d, st%d)
272 hm%kpoints => kpoints
273
274 !%Variable ParticleMass
275 !%Type float
276 !%Default 1.0
277 !%Section Hamiltonian
278 !%Description
279 !% It is possible to make calculations for a particle with a mass
280 !% different from one (atomic unit of mass, or mass of the electron).
281 !% This is useful to describe non-electronic systems, or for
282 !% esoteric purposes.
283 !%End
284 call parse_variable(namespace, 'ParticleMass', m_one, hm%mass)
286 !%Variable RashbaSpinOrbitCoupling
287 !%Type float
288 !%Default 0.0
289 !%Section Hamiltonian
290 !%Description
291 !% (Experimental.) For systems described in 2D (electrons confined to 2D in semiconductor structures), one
292 !% may add the Bychkov-Rashba spin-orbit coupling term [Bychkov and Rashba, <i>J. Phys. C: Solid
293 !% State Phys.</i> <b>17</b>, 6031 (1984)]. This variable determines the strength
294 !% of this perturbation, and has dimensions of energy times length.
295 !%End
296 call parse_variable(namespace, 'RashbaSpinOrbitCoupling', m_zero, rashba_coupling, units_inp%energy*units_inp%length)
297 if (parse_is_defined(namespace, 'RashbaSpinOrbitCoupling')) then
298 if (space%dim /= 2) then
299 write(message(1),'(a)') 'Rashba spin-orbit coupling can only be used for two-dimensional systems.'
300 call messages_fatal(1, namespace=namespace)
301 end if
302 call messages_experimental('RashbaSpinOrbitCoupling', namespace=namespace)
303 end if
304
305 call hm%hm_base%init(hm%d%nspin, hm%mass, rashba_coupling)
306 call hm%vnl%init()
308 assert(associated(gr%der%lapl))
309 hm%hm_base%kinetic => gr%der%lapl
311 safe_allocate(hm%energy)
313 !Keep pointers to derivatives, geometry and xc
314 hm%der => gr%der
315 hm%ions => ions
316 hm%xc => xc
318 if(present(xc_photons)) then
319 hm%xc_photons => xc_photons
320 else
321 hm%xc_photons => null()
322 end if
323
324 ! allocate potentials and density of the cores
325 ! In the case of spinors, vxc_11 = hm%vxc(:, 1), vxc_22 = hm%vxc(:, 2), Re(vxc_12) = hm%vxc(:. 3);
326 ! Im(vxc_12) = hm%vxc(:, 4)
327 safe_allocate(hm%vhxc(1:gr%np, 1:hm%d%nspin))
328 hm%vhxc(1:gr%np, 1:hm%d%nspin) = m_zero
329
330 if (hm%theory_level /= independent_particles) then
331
332 safe_allocate(hm%vhartree(1:gr%np_part))
333 hm%vhartree=m_zero
334
335 safe_allocate(hm%vxc(1:gr%np, 1:hm%d%nspin))
336 hm%vxc=m_zero
338 if (family_is_mgga_with_exc(hm%xc)) then
339 safe_allocate(hm%vtau(1:gr%np, 1:hm%d%nspin))
340 hm%vtau=m_zero
341 end if
342
343 end if
344
345 !Initialize Poisson solvers
346 call poisson_init(hm%psolver, namespace, space, gr%der, mc, gr%stencil, st%qtot)
347
348 ! Initialize external potential
349 call epot_init(hm%ep, namespace, gr, hm%ions, hm%psolver, hm%d%ispin, hm%xc%family, hm%kpoints)
350 call kick_init(hm%kick, namespace, space, hm%kpoints, hm%d%ispin)
351
352 hm%zora => zora_t(namespace, hm%der, hm%d, hm%ep, hm%mass)
353
354 !Temporary construction of the ion-electron interactions
355 call hm%v_ie_loc%init(gr, hm%psolver, hm%ions, namespace)
356 if (hm%ep%nlcc) then
357 call hm%nlcc%init(gr, hm%ions)
358 safe_allocate(st%rho_core(1:gr%np))
359 st%rho_core(:) = m_zero
360 end if
361
362 !Static magnetic field or rashba spin-orbit interaction requires complex wavefunctions
363 if (parse_is_defined(namespace, 'StaticMagneticField') .or. list_has_gauge_field(ext_partners) .or. &
364 parse_is_defined(namespace, 'RashbaSpinOrbitCoupling')) then
365 call states_set_complex(st)
366 end if
367
368 !%Variable CalculateSelfInducedMagneticField
369 !%Type logical
370 !%Default no
371 !%Section Hamiltonian
372 !%Description
373 !% The existence of an electronic current implies the creation of a self-induced magnetic
374 !% field, which may in turn back-react on the system. Of course, a fully consistent treatment
375 !% of this kind of effect should be done in QED theory, but we will attempt a first
376 !% approximation to the problem by considering the lowest-order relativistic terms
377 !% plugged into the normal Hamiltonian equations (spin-other-orbit coupling terms, etc.).
378 !% For the moment being, none of this is done, but a first step is taken by calculating
379 !% the induced magnetic field of a system that has a current, by considering the magnetostatic
380 !% approximation and Biot-Savart law:
381 !%
382 !% <math> \nabla^2 \vec{A} + 4\pi\alpha \vec{J} = 0</math>
383 !%
384 !% <math> \vec{B} = \vec{\nabla} \times \vec{A}</math>
385 !%
386 !% If <tt>CalculateSelfInducedMagneticField</tt> is set to yes, this <i>B</i> field is
387 !% calculated at the end of a <tt>gs</tt> calculation (nothing is done -- yet -- in the <tt>td</tt>case)
388 !% and printed out, if the <tt>Output</tt> variable contains the <tt>potential</tt> keyword (the prefix
389 !% of the output files is <tt>Bind</tt>).
390 !%End
391 call parse_variable(namespace, 'CalculateSelfInducedMagneticField', .false., hm%self_induced_magnetic)
392 if (hm%self_induced_magnetic) then
393 safe_allocate(hm%a_ind(1:gr%np_part, 1:space%dim))
394 safe_allocate(hm%b_ind(1:gr%np_part, 1:space%dim))
395
396 !(for dim = we could save some memory, but it is better to keep it simple)
397 end if
398
399 ! Absorbing boundaries
400 call absorbing_boundaries_init(hm%abs_boundaries, namespace, space, gr)
401
402 hm%inh_term = .false.
403 call oct_exchange_remove(hm%oct_exchange)
404
405 hm%adjoint = .false.
406
407 call hm%phase%init(gr, hm%d%kpt, hm%kpoints, st%d, space)
408
409 !%Variable DFTULevel
410 !%Type integer
411 !%Default no
412 !%Section Hamiltonian::XC
413 !%Description
414 !% This variable selects which DFT+U expression is added to the Hamiltonian.
415 !%Option dft_u_none 0
416 !% No +U term is not applied.
417 !%Option dft_u_empirical 1
418 !% An empiricial Hubbard U is added on the orbitals specified in the block species
419 !% with hubbard_l and hubbard_u
420 !%Option dft_u_acbn0 2
421 !% Octopus determines the effective U term using the
422 !% ACBN0 functional as defined in PRX 5, 011006 (2015)
423 !%End
424 call parse_variable(namespace, 'DFTULevel', dft_u_none, hm%lda_u_level)
425 call messages_print_var_option('DFTULevel', hm%lda_u_level, namespace=namespace)
426 if (hm%lda_u_level /= dft_u_none) then
427 call lda_u_init(hm%lda_u, namespace, space, hm%lda_u_level, gr, ions, st, mc, &
428 hm%kpoints, hm%phase%is_allocated())
429
430 !In the present implementation of DFT+U, in case of spinors, we have off-diagonal terms
431 !in spin space which break the assumption of the generalized Bloch theorem
432 if (kick_get_type(hm%kick) == kick_magnon_mode .and. gr%der%boundaries%spiral) then
433 call messages_not_implemented("DFT+U with generalized Bloch theorem and magnon kick", namespace=namespace)
434 end if
435
436 ! We rebuild the phase for the orbital projection, similarly to the one of the pseudopotentials
437 if(hm%lda_u_level /= dft_u_none .and. hm%phase%is_allocated()) then
438 call lda_u_build_phase_correction(hm%lda_u, space, hm%d, gr%der%boundaries, namespace, hm%kpoints)
439 end if
440 end if
441
442 !%Variable HamiltonianApplyPacked
443 !%Type logical
444 !%Default yes
445 !%Section Execution::Optimization
446 !%Description
447 !% If set to yes (the default), Octopus will 'pack' the
448 !% wave-functions when operating with them. This might involve some
449 !% additional copying but makes operations more efficient.
450 !% See also the related <tt>StatesPack</tt> variable.
451 !%End
452 call parse_variable(namespace, 'HamiltonianApplyPacked', .true., hm%is_applied_packed)
453
454 if (hm%theory_level == hartree_fock .and. st%parallel_in_states) then
455 call messages_experimental('Hartree-Fock parallel in states', namespace=namespace)
456 end if
457
458 if (hm%theory_level == generalized_kohn_sham_dft .and. family_is_hybrid(hm%xc) &
459 .and. st%parallel_in_states) then
460 call messages_experimental('Hybrid functionals parallel in states', namespace=namespace)
461 end if
462
463
464 !%Variable TimeZero
465 !%Type logical
466 !%Default no
467 !%Section Hamiltonian
468 !%Description
469 !% (Experimental) If set to yes, the ground state and other time
470 !% dependent calculation will assume that they are done at time
471 !% zero, so that all time depedent field at that time will be
472 !% included.
473 !%End
474 call parse_variable(namespace, 'TimeZero', .false., hm%time_zero)
475 if (hm%time_zero) call messages_experimental('TimeZero', namespace=namespace)
476
477 !Cam parameters are irrelevant here and are updated later
478 need_exchange_ = optional_default(need_exchange, .false.)
479 if (hm%theory_level == hartree_fock .or. hm%theory_level == hartree &
480 .or. hm%theory_level == rdmft .or. need_exchange_ .or. &
481 (hm%theory_level == generalized_kohn_sham_dft .and. family_is_hybrid(hm%xc)) &
482 .or. hm%xc%functional(func_x,1)%id == xc_oep_x_slater &
483 .or. bitand(hm%xc%family, xc_family_oep) /= 0) then
484 !We test Slater before OEP, as Slater is treated as OEP for the moment....
485 if (hm%xc%functional(func_x,1)%id == xc_oep_x_slater) then
486 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
487 hm%kpoints, m_zero, m_one, m_zero)
488 else if (bitand(hm%xc%family, xc_family_oep) /= 0 .or. hm%theory_level == rdmft) then
489 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
490 hm%kpoints, hm%xc%cam_omega, hm%xc%cam_alpha, hm%xc%cam_beta)
491 else
492 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
493 hm%kpoints, m_zero, m_one, m_zero)
494 end if
495 end if
496
497 if (hm%is_applied_packed .and. accel_is_enabled()) then
498 ! Check if we can actually apply the hamiltonian packed
499 if (gr%use_curvilinear) then
500 if (accel_allow_cpu_only()) then
501 hm%is_applied_packed = .false.
502 call messages_write('Cannot use CUDA or OpenCL as curvilinear coordinates are used.')
503 call messages_warning(namespace=namespace)
504 else
505 call messages_write('Cannot use CUDA or OpenCL as curvilinear coordinates are used.', new_line = .true.)
506 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
507 call messages_fatal(namespace=namespace)
508 end if
509 end if
510 end if
511
512 !We are building the list of external potentials
513 !This is done here at the moment, because we pass directly the mesh
514 !TODO: Once the abstract Hamiltonian knows about an abstract basis, we might move this to the
515 ! abstract Hamiltonian
516 call load_external_potentials(hm%external_potentials, namespace)
517
518 !Some checks which are electron specific, like k-points
520
521 !At the moment we do only have static external potential, so we never update them
523
524 !Build the resulting interactions
525 !TODO: This will be moved to the actual interactions
526 call build_interactions()
527
528 call magnetic_constrain_init(hm%magnetic_constrain, namespace, gr, st%d, st%rho, ions%natoms, ions%min_distance())
529
530 ! init maxwell-electrons coupling
531 call mxll_coupling_init(hm%mxll, st%d, gr, namespace, hm%mass)
532
533 if (associated(hm%xc_photons)) then
534 if (hm%xc_photons%wants_to_renormalize_mass()) then
535 ! remornalize the electron mass due to light-matter interaction; here we only deal with it in free space
536 call hm%set_mass(namespace, hm%xc_photons%get_renormalized_mass())
537 end if
538 end if
539
540
541 call profiling_out('HAMILTONIAN_ELEC_INIT')
542 pop_sub(hamiltonian_elec_init)
543
544 contains
545
546 ! ---------------------------------------------------------
547 subroutine build_external_potentials()
548 type(list_iterator_t) :: iter
549 class(*), pointer :: potential
550 integer :: iop
551
553
554 safe_allocate(hm%v_ext_pot(1:gr%np))
555 hm%v_ext_pot(1:gr%np) = m_zero
556
557 call iter%start(hm%external_potentials)
558 do while (iter%has_next())
559 potential => iter%get_next()
560 select type (potential)
561 class is (external_potential_t)
562
563 call potential%allocate_memory(gr)
564 call potential%calculate(namespace, gr, hm%psolver)
565 !To preserve the old behavior, we are adding the various potentials
566 !to the corresponding arrays
567 select case (potential%type)
569 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_ext_pot)
570
572 if (.not. allocated(hm%ep%b_field)) then
573 safe_allocate(hm%ep%b_field(1:3)) !Cannot be space%dim
574 hm%ep%b_field(1:3) = m_zero
575 end if
576 hm%ep%b_field(1:3) = hm%ep%b_field(1:3) + potential%b_field(1:3)
577
578 if (.not. allocated(hm%ep%a_static)) then
579 safe_allocate(hm%ep%a_static(1:gr%np, 1:space%dim))
580 hm%ep%a_static(1:gr%np, 1:space%dim) = m_zero
581 end if
582 call lalg_axpy(gr%np, space%dim, m_one, potential%a_static, hm%ep%a_static)
583
585 if (.not. allocated(hm%ep%e_field)) then
586 safe_allocate(hm%ep%e_field(1:space%dim))
587 hm%ep%e_field(1:space%dim) = m_zero
588 end if
589 hm%ep%e_field(1:space%dim) = hm%ep%e_field(1:space%dim) + potential%e_field(1:space%dim)
590
591 !In the fully periodic case, we use Berry phases
592 if (space%periodic_dim < space%dim) then
593 if (.not. allocated(hm%v_static)) then
594 safe_allocate(hm%v_static(1:gr%np))
595 hm%v_static(1:gr%np) = m_zero
596 end if
597 if (.not. allocated(hm%ep%v_ext)) then
598 safe_allocate(hm%ep%v_ext(1:gr%np_part))
599 hm%ep%v_ext(1:gr%np_part) = m_zero
600 end if
601 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_static)
602 call lalg_axpy(gr%np, m_one, potential%v_ext, hm%ep%v_ext)
603 end if
604
605 if (hm%kpoints%use_symmetries) then
606 do iop = 1, symmetries_number(hm%kpoints%symm)
607 if (iop == symmetries_identity_index(hm%kpoints%symm)) cycle
608 if (.not. symm_op_invariant_cart(hm%kpoints%symm%ops(iop), hm%ep%e_field, 1e-5_real64)) then
609 message(1) = "The StaticElectricField breaks (at least) one of the symmetries used to reduce the k-points."
610 message(2) = "Set SymmetryBreakDir equal to StaticElectricField."
611 call messages_fatal(2, namespace=namespace)
612 end if
613 end do
614 end if
615
616 end select
617 call potential%deallocate_memory()
618
619 class default
620 assert(.false.)
621 end select
622 end do
623
625 end subroutine build_external_potentials
626
627 ! ---------------------------------------------------------
628 subroutine external_potentials_checks()
629 type(list_iterator_t) :: iter
630 class(*), pointer :: potential
631
633
634 call iter%start(hm%external_potentials)
635 do while (iter%has_next())
636 potential => iter%get_next()
637 select type (potential)
638 class is (external_potential_t)
639
640 if (potential%type == external_pot_static_efield .and. hm%kpoints%reduced%npoints > 1) then
641 message(1) = "Applying StaticElectricField in a periodic direction is only accurate for large supercells."
642 message(2) = "Single-point Berry phase is not appropriate when k-point sampling is needed."
643 call messages_warning(2, namespace=namespace)
644 end if
645
646 class default
647 assert(.false.)
648 end select
649 end do
650
652 end subroutine external_potentials_checks
653
654
655 !The code in this routines needs to know about the external potentials.
656 !This will be treated in the future by the interactions directly.
657 subroutine build_interactions()
658 logical :: external_potentials_present
659 logical :: kick_present
660
662
663 if (allocated(hm%ep%e_field) .and. space%is_periodic() .and. .not. list_has_gauge_field(ext_partners)) then
664 ! only need vberry if there is a field in a periodic direction
665 ! and we are not setting a gauge field
666 if (any(abs(hm%ep%e_field(1:space%periodic_dim)) > m_epsilon)) then
667 safe_allocate(hm%vberry(1:gr%np, 1:hm%d%nspin))
668 hm%vberry = m_zero
669 end if
670 end if
671
672 external_potentials_present = epot_have_external_potentials(hm%ep) .or. &
673 list_has_lasers(ext_partners) .or. allocated(hm%v_static)
674
675
676 kick_present = hamiltonian_elec_has_kick(hm)
677
678 call pcm_init(hm%pcm, namespace, space, ions, gr, st%qtot, st%val_charge, external_potentials_present, kick_present)
679 if (hm%pcm%run_pcm) then
680 if (hm%theory_level /= kohn_sham_dft) call messages_not_implemented("PCM for TheoryLevel /= kohn_sham", namespace=namespace)
681 end if
682
684
685 end subroutine build_interactions
686
687
688 end subroutine hamiltonian_elec_init
689
690
691 ! ---------------------------------------------------------
692 subroutine hamiltonian_elec_end(hm)
693 type(hamiltonian_elec_t), target, intent(inout) :: hm
694
695 type(partner_iterator_t) :: iter
696 class(interaction_partner_t), pointer :: potential
697
698 push_sub(hamiltonian_elec_end)
699
700 call hm%hm_base%end()
701 call hm%vnl%end()
702
703 call hm%phase%end()
704
705 safe_deallocate_a(hm%vhartree)
706 safe_deallocate_a(hm%vhxc)
707 safe_deallocate_a(hm%vxc)
708 safe_deallocate_a(hm%vberry)
709 safe_deallocate_a(hm%a_ind)
710 safe_deallocate_a(hm%b_ind)
711 safe_deallocate_a(hm%v_ext_pot)
712
713 safe_deallocate_p(hm%zora)
714
715 if (family_is_mgga_with_exc(hm%xc)) then
716 safe_deallocate_a(hm%vtau)
717 end if
718
719 call poisson_end(hm%psolver)
720
721 nullify(hm%xc)
722
723 call kick_end(hm%kick)
724 call epot_end(hm%ep)
725 nullify(hm%ions)
726
727 call absorbing_boundaries_end(hm%abs_boundaries)
728
729 call states_elec_dim_end(hm%d)
730
731 if (hm%scissor%apply) call scissor_end(hm%scissor)
732
733 call exchange_operator_end(hm%exxop)
734 call lda_u_end(hm%lda_u)
735
736 safe_deallocate_a(hm%energy)
737
738 if (hm%pcm%run_pcm) call pcm_end(hm%pcm)
739
740 call hm%v_ie_loc%end()
741 call hm%nlcc%end()
742
743 call iter%start(hm%external_potentials)
744 do while (iter%has_next())
745 potential => iter%get_next()
746 safe_deallocate_p(potential)
747 end do
748 call hm%external_potentials%empty()
749 safe_deallocate_a(hm%v_static)
751 call magnetic_constrain_end(hm%magnetic_constrain)
752
753 call mxll_coupling_end(hm%mxll)
754
755 pop_sub(hamiltonian_elec_end)
756 end subroutine hamiltonian_elec_end
757
758
759 ! ---------------------------------------------------------
760 ! True if the Hamiltonian is Hermitian, false otherwise
761 logical function hamiltonian_elec_hermitian(hm)
762 class(hamiltonian_elec_t), intent(in) :: hm
763
765 hamiltonian_elec_hermitian = .not.((hm%abs_boundaries%abtype == imaginary_absorbing) .or. &
766 oct_exchange_enabled(hm%oct_exchange))
767
769 end function hamiltonian_elec_hermitian
770
771
772 ! ---------------------------------------------------------
773 subroutine hamiltonian_elec_span(hm, delta, emin, namespace)
774 class(hamiltonian_elec_t), intent(inout) :: hm
775 real(real64), intent(in) :: delta(:)
776 real(real64), intent(in) :: emin
777 type(namespace_t), intent(in) :: namespace
778
779 real(real64) :: emax
780
781 push_sub(hamiltonian_elec_span)
782
783 ! estimate maximum energy of discrete kinetic operator
784 ! this neglects possible contributions from the non-local part of the pseudopotentials
786
787 hm%spectral_middle_point = (emax + emin) / m_two
788 hm%spectral_half_span = (emax - emin) / m_two
789
790 pop_sub(hamiltonian_elec_span)
791 end subroutine hamiltonian_elec_span
792
793
794 ! ---------------------------------------------------------
795 pure logical function hamiltonian_elec_inh_term(hm) result(inh)
796 type(hamiltonian_elec_t), intent(in) :: hm
797
798 inh = hm%inh_term
799 end function hamiltonian_elec_inh_term
800
801
802 ! ---------------------------------------------------------
803 subroutine hamiltonian_elec_set_inh(hm, st)
804 type(hamiltonian_elec_t), intent(inout) :: hm
805 type(states_elec_t), intent(in) :: st
806
808
809 if (hm%inh_term) call states_elec_end(hm%inh_st)
810 call states_elec_copy(hm%inh_st, st)
811 hm%inh_term = .true.
812
814 end subroutine hamiltonian_elec_set_inh
815
816
817 ! ---------------------------------------------------------
818 subroutine hamiltonian_elec_remove_inh(hm)
819 type(hamiltonian_elec_t), intent(inout) :: hm
820
822
823 if (hm%inh_term) then
824 call states_elec_end(hm%inh_st)
825 hm%inh_term = .false.
826 end if
827
829 end subroutine hamiltonian_elec_remove_inh
830
831 ! ---------------------------------------------------------
832 subroutine hamiltonian_elec_adjoint(hm)
833 type(hamiltonian_elec_t), intent(inout) :: hm
834
836
837 if (.not. hm%adjoint) then
838 hm%adjoint = .true.
839 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
840 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
841 end if
842 end if
843
845 end subroutine hamiltonian_elec_adjoint
846
847
848 ! ---------------------------------------------------------
849 subroutine hamiltonian_elec_not_adjoint(hm)
850 type(hamiltonian_elec_t), intent(inout) :: hm
851
853
854 if (hm%adjoint) then
855 hm%adjoint = .false.
856 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
857 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
858 end if
859 end if
860
862 end subroutine hamiltonian_elec_not_adjoint
863
864
865 ! ---------------------------------------------------------
867 subroutine hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
868 class(hamiltonian_elec_t), intent(inout) :: this
869 class(mesh_t), intent(in) :: mesh
870 type(namespace_t), intent(in) :: namespace
871 class(space_t), intent(in) :: space
872 type(partner_list_t), intent(in) :: ext_partners
873 real(real64), optional, intent(in) :: time
874
875 integer :: ispin, ip, idir, iatom, ilaser
876 real(real64) :: aa(space%dim), time_
877 real(real64), allocatable :: vp(:,:)
878 type(lasers_t), pointer :: lasers
879 type(gauge_field_t), pointer :: gfield
880 real(real64) :: am(space%dim)
881
883 call profiling_in("HAMILTONIAN_ELEC_UPDATE")
884
885 this%current_time = m_zero
886 if (present(time)) this%current_time = time
887
888 time_ = optional_default(time, 0.0_real64)
889
890 ! set everything to zero
891 call this%hm_base%clear(mesh%np)
892
893 ! alllocate the scalar potential for the xc, hartree and external potentials
894 call this%hm_base%allocate_field(mesh, field_potential, &
895 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
897 ! the lasers
898 if (present(time) .or. this%time_zero) then
899
900 lasers => list_get_lasers(ext_partners)
901 if(associated(lasers)) then
902 do ilaser = 1, lasers%no_lasers
903 select case (laser_kind(lasers%lasers(ilaser)))
905 do ispin = 1, this%d%spin_channels
906 call laser_potential(lasers%lasers(ilaser), mesh, &
907 this%hm_base%potential(:, ispin), time_)
908 end do
909 case (e_field_magnetic)
910 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, &
911 .false.)
912 ! get the vector potential
913 safe_allocate(vp(1:mesh%np, 1:space%dim))
914 vp(1:mesh%np, 1:space%dim) = m_zero
915 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
916 !$omp parallel do private(idir) schedule(static)
917 do ip = 1, mesh%np
918 do idir = 1, space%dim
919 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + vp(ip, idir)/p_c
920 end do
921 end do
922 ! and the magnetic field
923 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
924 safe_deallocate_a(vp)
926 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
927 ! get the uniform vector potential associated with a magnetic field
928 aa = m_zero
929 call laser_field(lasers%lasers(ilaser), aa, time_)
930 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
931 end select
932 end do
933
934 if (lasers_with_nondipole_field(lasers)) then
935 assert( allocated(this%hm_base%uniform_vector_potential))
936 call lasers_nondipole_laser_field_step(lasers, am, time_)
937 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - am/p_c
938 end if
939 end if
940
941 ! the gauge field
942 gfield => list_get_gauge_field(ext_partners)
943 if (associated(gfield)) then
944 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
945 call gauge_field_get_vec_pot(gfield, aa)
946 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
947 end if
948
949 ! the electric field for a periodic system through the gauge field
950 if (allocated(this%ep%e_field) .and. associated(gfield)) then
951 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
952 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
953 end if
954
955 ! add the photon-free mean-field vector potential
956 if (associated(this%xc_photons)) then
957 if(this%xc_photons%lpfmf .and. allocated(this%xc_photons%mf_vector_potential)) then
958 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
959 ! here we put a minus sign in front of the mean field term to get the right answer (need to check the formula)
960 this%hm_base%uniform_vector_potential(1:space%dim) = &
961 this%hm_base%uniform_vector_potential(1:space%dim) - this%xc_photons%mf_vector_potential(1:space%dim)/p_c
962 end if
963 end if
964
965 end if
966
967 ! the vector potential of a static magnetic field
968 if (allocated(this%ep%a_static)) then
969 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
970 !ep%a_static contains 1/c A(r)
971 !$omp parallel do private(idir) schedule(static)
972 do ip = 1, mesh%np
973 do idir = 1, space%dim
974 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
975 end do
976 end do
977 end if
978
979 ! add Maxwell coupling to Hamiltonian and sets the magnetic field for the Zeeman term added below
980 call mxll_coupling_calc(this%mxll, this%hm_base, mesh, this%d, space)
981
982 !The electric field was added to the KS potential
983 if (family_is_mgga_with_exc(this%xc)) then
984 call this%hm_base%accel_copy_pot(mesh, this%vtau)
985 else
986 call this%hm_base%accel_copy_pot(mesh)
987 end if
988
989 ! and the static magnetic field
990 if (allocated(this%ep%b_field)) then
991 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
992 do idir = 1, 3
993 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
994 end do
995 end if
996
997 ! Combine the uniform and non-uniform fields and compute the Zeeman term
998 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
999
1000 ! This needs to be called at the end as the zeeman term enters the potential
1001 call hamiltonian_elec_update_pot(this, mesh, accumulate = .true.)
1002
1003 if (this%mxll%test_equad) then
1004 call set_electric_quadrupole_pot(this%mxll, mesh)
1005 end if
1006
1007 call build_phase()
1008
1009 call profiling_out("HAMILTONIAN_ELEC_UPDATE")
1011
1012 contains
1013
1014 subroutine build_phase()
1015 integer :: ik, imat, nmat, max_npoints, offset
1016 integer :: ip
1017 integer :: iphase, nphase
1018
1020
1021 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1022
1023 call profiling_in('UPDATE_PHASES')
1024 ! now regenerate the phases for the pseudopotentials
1025 do iatom = 1, this%ep%natoms
1026 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1027 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1028 end do
1029
1030 call profiling_out('UPDATE_PHASES')
1031 end if
1032
1033 if (allocated(this%hm_base%uniform_vector_potential)) then
1034
1035 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1036
1037 ! We rebuild the phase for the orbital projection, similarly to the one of the pseudopotentials
1038 if (this%lda_u_level /= dft_u_none) then
1039 call lda_u_build_phase_correction(this%lda_u, space, this%d, this%der%boundaries, namespace, this%kpoints, &
1040 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1041 end if
1042 end if
1043
1044 max_npoints = this%vnl%max_npoints
1045 nmat = this%vnl%nprojector_matrices
1046
1047
1048 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1049
1050 nphase = 1
1051 if (this%der%boundaries%spiralBC) nphase = 3
1052
1053 if (.not. allocated(this%vnl%projector_phases)) then
1054 safe_allocate(this%vnl%projector_phases(1:max_npoints, 1:nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1055 if (accel_is_enabled()) then
1056 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1057 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1058 ! We need to save nphase, with which the array has been build,
1059 ! as the number might change throughout the run
1060 this%vnl%nphase = nphase
1061 end if
1062 end if
1063
1064 offset = 0
1065 do ik = this%d%kpt%start, this%d%kpt%end
1066 do imat = 1, this%vnl%nprojector_matrices
1067 iatom = this%vnl%projector_to_atom(imat)
1068 do iphase = 1, nphase
1069 !$omp parallel do simd schedule(static)
1070 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1071 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1072 end do
1073
1074 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1075 call accel_write_buffer(this%vnl%buff_projector_phases, &
1076 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1077 offset = offset, async=.true.)
1078 end if
1079 offset = offset + this%vnl%projector_matrices(imat)%npoints
1080 end do
1081 end do
1082 end do
1083
1084 end if
1085
1086 call accel_finish()
1087
1089 end subroutine build_phase
1090
1091 end subroutine hamiltonian_elec_update
1092
1093
1094 !----------------------------------------------------------------
1097 ! TODO: See Issue #1064
1098 subroutine hamiltonian_elec_update_pot(this, mesh, accumulate)
1099 type(hamiltonian_elec_t), intent(inout) :: this
1100 class(mesh_t), intent(in) :: mesh
1101 logical, optional, intent(in) :: accumulate
1102
1103 integer :: ispin, ip
1104
1106
1107 ! By default we nullify first the result
1108 if (.not. optional_default(accumulate, .false.)) then
1109 !$omp parallel private(ip, ispin)
1110 do ispin = 1, this%d%nspin
1111 !$omp do simd schedule(static)
1112 do ip = 1, mesh%np
1113 this%hm_base%potential(ip, ispin) = m_zero
1114 end do
1115 end do
1116 !$omp end parallel
1117 end if
1118
1119 !$omp parallel private(ip, ispin)
1120 do ispin = 1, this%d%nspin
1121 if (ispin <= 2) then
1122 !$omp do simd schedule(static)
1123 ! this%vhxc(ip, ispin) is added after the calculation of ZORA potential
1124 do ip = 1, mesh%np
1125 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%ep%vpsl(ip) + this%v_ext_pot(ip)
1126 end do
1127
1129 if (this%pcm%run_pcm) then
1130 if (this%pcm%solute) then
1131 !$omp do simd schedule(static)
1132 do ip = 1, mesh%np
1133 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1134 this%pcm%v_e_rs(ip) + this%pcm%v_n_rs(ip)
1135 end do
1136 !$omp end do simd nowait
1137 end if
1138 if (this%pcm%localf) then
1139 !$omp do simd schedule(static)
1140 do ip = 1, mesh%np
1141 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1142 this%pcm%v_ext_rs(ip)
1143 end do
1144 !$omp end do simd nowait
1145 end if
1146 end if
1147
1149 if (this%abs_boundaries%abtype == imaginary_absorbing) then
1150 !$omp do simd schedule(static)
1151 do ip = 1, mesh%np
1152 this%hm_base%Impotential(ip, ispin) = this%hm_base%Impotential(ip, ispin) + this%abs_boundaries%mf(ip)
1153 end do
1154 !$omp end do simd nowait
1155 end if
1156 end if
1157 end do
1158 !$omp end parallel
1159
1160 ! scalar relativistic ZORA contribution
1161 ! \boldsymbol{p} \frac{c^2}{2c^2 - V} \boldsymbol{p} \Phi^\mathrm{ZORA}
1162 if (this%ep%reltype == scalar_relativistic_zora .or. this%ep%reltype == fully_relativistic_zora) then
1163 call this%zora%update(this%der, this%hm_base%potential)
1164 end if
1165
1166 !$omp parallel private(ip, ispin)
1167 do ispin = 1, this%d%nspin
1168 ! Adding the magnetic constrain potential
1169 if (this%magnetic_constrain%level /= constrain_none) then
1170 !$omp do simd schedule(static)
1171 do ip = 1, mesh%np
1172 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%magnetic_constrain%pot(ip, ispin)
1173 end do
1174 !$omp end do simd nowait
1175 end if
1176
1177 ! Adding Zeeman potential to hm_base%potential
1178 if (allocated(this%hm_base%zeeman_pot)) then
1179 !$omp do simd schedule(static)
1180 do ip = 1, mesh%np
1181 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%hm_base%zeeman_pot(ip, ispin)
1182 end do
1183 !$omp end do simd nowait
1184 end if
1185
1186 ! Adding Quadrupole potential from static E-field (test)
1187 if (this%mxll%test_equad) then
1188 !$omp do simd schedule(static)
1189 do ip = 1, mesh%np
1190 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%mxll%e_quadrupole_pot(ip)
1191 end do
1192 !$omp end do simd
1193 end if
1194 end do
1195 !$omp end parallel
1196
1197
1198 !$omp parallel private(ip, ispin)
1199 do ispin = 1, this%d%nspin
1200 !$omp do simd schedule(static)
1201 do ip = 1, mesh%np
1202 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%vhxc(ip, ispin)
1203 end do
1204 !$omp end do simd nowait
1205 end do
1206 !$omp end parallel
1207
1208 if (family_is_mgga_with_exc(this%xc)) then
1209 call this%hm_base%accel_copy_pot(mesh, this%vtau)
1210 else
1211 call this%hm_base%accel_copy_pot(mesh)
1212 end if
1213
1215 end subroutine hamiltonian_elec_update_pot
1216
1217 ! ---------------------------------------------------------
1218 subroutine hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
1219 type(hamiltonian_elec_t), intent(inout) :: this
1220 type(namespace_t), intent(in) :: namespace
1221 class(electron_space_t), intent(in) :: space
1222 type(grid_t), intent(in) :: gr
1223 type(ions_t), target, intent(inout) :: ions
1224 type(partner_list_t), intent(in) :: ext_partners
1225 type(states_elec_t), intent(inout) :: st
1226 real(real64), optional, intent(in) :: time
1227
1229
1230 this%ions => ions
1231 call epot_generate(this%ep, namespace, gr, this%ions, this%d)
1232
1233 ! Interation terms are treated below
1234
1235 ! First we add the static electric field
1236 if (allocated(this%ep%e_field) .and. space%periodic_dim < space%dim) then
1237 call lalg_axpy(gr%np, m_one, this%v_static, this%ep%vpsl)
1238 end if
1239
1240 ! Here we need to pass this again, else test are failing.
1241 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1242 this%v_ie_loc%atoms_dist => ions%atoms_dist
1243 this%v_ie_loc%atom => ions%atom
1244 call this%v_ie_loc%calculate()
1245
1246 ! At the moment we need to add this to ep%vpsl, to keep the behavior of the code
1247 call lalg_axpy(gr%np, m_one, this%v_ie_loc%potential(:,1), this%ep%vpsl)
1248
1249 ! Here we need to pass this again, else test are failing.
1250 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1251 if (this%ep%nlcc) then
1252 this%nlcc%atoms_dist => ions%atoms_dist
1253 this%nlcc%atom => ions%atom
1254 call this%nlcc%calculate()
1255 call lalg_copy(gr%np, this%nlcc%density(:,1), st%rho_core)
1256 end if
1257
1258 call this%vnl%build(space, gr, this%ep)
1259 call hamiltonian_elec_update(this, gr, namespace, space, ext_partners, time)
1260
1261 ! Check if projectors are still compatible with apply_packed on GPU
1262 if (this%is_applied_packed .and. accel_is_enabled()) then
1263 if (this%ep%non_local .and. .not. this%vnl%apply_projector_matrices) then
1264 if (accel_allow_cpu_only()) then
1265 call messages_write('Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.')
1266 call messages_warning(namespace=namespace)
1267 else
1268 call messages_write('Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.',&
1269 new_line = .true.)
1270 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
1271 call messages_fatal(namespace=namespace)
1272 end if
1273 end if
1274
1275 end if
1276
1277 if (this%pcm%run_pcm) then
1280 if (this%pcm%solute) then
1281 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, ions = ions)
1282 end if
1283
1286 ! Interpolation is needed, hence gr%np_part -> 1:gr%np
1287 if (this%pcm%localf .and. allocated(this%v_static)) then
1288 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, v_ext = this%ep%v_ext(1:gr%np_part))
1289 end if
1290
1291 end if
1292
1293 call lda_u_update_basis(this%lda_u, space, gr, ions, st, this%psolver, namespace, this%kpoints, &
1294 this%phase%is_allocated())
1295
1297 end subroutine hamiltonian_elec_epot_generate
1298
1299 ! -----------------------------------------------------------------
1300
1301 real(real64) function hamiltonian_elec_get_time(this) result(time)
1302 type(hamiltonian_elec_t), intent(inout) :: this
1303
1304 time = this%current_time
1305 end function hamiltonian_elec_get_time
1306
1307 ! -----------------------------------------------------------------
1308
1309 pure logical function hamiltonian_elec_apply_packed(this) result(apply)
1310 class(hamiltonian_elec_t), intent(in) :: this
1312 apply = this%is_applied_packed
1313
1315
1316
1317 ! -----------------------------------------------------------------
1318 subroutine zhamiltonian_elec_apply_atom (hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
1319 type(hamiltonian_elec_t), intent(in) :: hm
1320 type(namespace_t), intent(in) :: namespace
1321 class(space_t), intent(in) :: space
1322 type(lattice_vectors_t), intent(in) :: latt
1323 class(species_t), intent(in) :: species
1324 real(real64), intent(in) :: pos(1:space%dim)
1325 integer, intent(in) :: ia
1326 class(mesh_t), intent(in) :: mesh
1327 complex(real64), intent(in) :: psi(:,:)
1328 complex(real64), intent(out) :: vpsi(:,:)
1329
1330 integer :: idim
1331 real(real64), allocatable :: vlocal(:)
1333
1334 safe_allocate(vlocal(1:mesh%np_part))
1335 vlocal = m_zero
1336 call epot_local_potential(hm%ep, namespace, space, latt, mesh, species, pos, ia, vlocal)
1337
1338 do idim = 1, hm%d%dim
1339 vpsi(1:mesh%np, idim) = vlocal(1:mesh%np) * psi(1:mesh%np, idim)
1340 end do
1341
1342 safe_deallocate_a(vlocal)
1344 end subroutine zhamiltonian_elec_apply_atom
1345
1346
1347 ! -----------------------------------------------------------------
1348 subroutine hamiltonian_elec_dump_vhxc(restart, hm, space, mesh, ierr)
1349 type(restart_t), intent(in) :: restart
1350 type(hamiltonian_elec_t), intent(in) :: hm
1351 class(space_t), intent(in) :: space
1352 class(mesh_t), intent(in) :: mesh
1353 integer, intent(out) :: ierr
1354
1355 integer :: iunit, err, err2(2), isp
1356 character(len=12) :: filename
1357 character(len=100) :: lines(2)
1358
1360
1361 ierr = 0
1362
1363 if (restart_skip(restart) .or. hm%theory_level == independent_particles) then
1365 return
1366 end if
1367
1368 if (debug%info) then
1369 message(1) = "Debug: Writing Vhxc restart."
1370 call messages_info(1)
1371 end if
1372
1373 !write the different components of the Hartree+XC potential
1374 iunit = restart_open(restart, 'vhxc')
1375 lines(1) = '# #spin #nspin filename'
1376 lines(2) = '%vhxc'
1377 call restart_write(restart, iunit, lines, 2, err)
1378 if (err /= 0) ierr = ierr + 1
1379
1380 err2 = 0
1381 do isp = 1, hm%d%nspin
1382 if (hm%d%nspin == 1) then
1383 write(filename, fmt='(a)') 'vhxc'
1384 else
1385 write(filename, fmt='(a,i1)') 'vhxc-sp', isp
1386 end if
1387 write(lines(1), '(i8,a,i8,a)') isp, ' | ', hm%d%nspin, ' | "'//trim(adjustl(filename))//'"'
1388 call restart_write(restart, iunit, lines, 1, err)
1389 if (err /= 0) err2(1) = err2(1) + 1
1390
1391 call restart_write_mesh_function(restart, space, filename, mesh, hm%vhxc(:,isp), err)
1392 if (err /= 0) err2(2) = err2(2) + 1
1393
1394 end do
1395 if (err2(1) /= 0) ierr = ierr + 2
1396 if (err2(2) /= 0) ierr = ierr + 4
1397
1398 lines(1) = '%'
1399 call restart_write(restart, iunit, lines, 1, err)
1400 if (err /= 0) ierr = ierr + 4
1401
1402 ! MGGAs and hybrid MGGAs have an extra term that also needs to be dumped
1403 if (family_is_mgga_with_exc(hm%xc)) then
1404 lines(1) = '# #spin #nspin filename'
1405 lines(2) = '%vtau'
1406 call restart_write(restart, iunit, lines, 2, err)
1407 if (err /= 0) ierr = ierr + 8
1408
1409 err2 = 0
1410 do isp = 1, hm%d%nspin
1411 if (hm%d%nspin == 1) then
1412 write(filename, fmt='(a)') 'vtau'
1413 else
1414 write(filename, fmt='(a,i1)') 'vtau-sp', isp
1415 end if
1416 write(lines(1), '(i8,a,i8,a)') isp, ' | ', hm%d%nspin, ' | "'//trim(adjustl(filename))//'"'
1417 call restart_write(restart, iunit, lines, 1, err)
1418 if (err /= 0) err2(1) = err2(1) + 16
1419
1420 call restart_write_mesh_function(restart, space, filename, mesh, hm%vtau(:,isp), err)
1421 if (err /= 0) err2(1) = err2(1) + 1
1422
1423 end do
1424 if (err2(1) /= 0) ierr = ierr + 32
1425 if (err2(2) /= 0) ierr = ierr + 64
1426
1427 lines(1) = '%'
1428 call restart_write(restart, iunit, lines, 1, err)
1429 if (err /= 0) ierr = ierr + 128
1430 end if
1431
1432 call restart_close(restart, iunit)
1433
1434 if (debug%info) then
1435 message(1) = "Debug: Writing Vhxc restart done."
1436 call messages_info(1)
1437 end if
1438
1440 end subroutine hamiltonian_elec_dump_vhxc
1442
1443 ! ---------------------------------------------------------
1444 subroutine hamiltonian_elec_load_vhxc(restart, hm, space, mesh, ierr)
1445 type(restart_t), intent(in) :: restart
1446 type(hamiltonian_elec_t), intent(inout) :: hm
1447 class(space_t), intent(in) :: space
1448 class(mesh_t), intent(in) :: mesh
1449 integer, intent(out) :: ierr
1450
1451 integer :: err, err2, isp
1452 character(len=12) :: filename
1453
1455
1456 ierr = 0
1457
1458 if (restart_skip(restart) .or. hm%theory_level == independent_particles) then
1459 ierr = -1
1461 return
1462 end if
1463
1464 if (debug%info) then
1465 message(1) = "Debug: Reading Vhxc restart."
1466 call messages_info(1)
1467 end if
1468
1469 err2 = 0
1470 do isp = 1, hm%d%nspin
1471 if (hm%d%nspin == 1) then
1472 write(filename, fmt='(a)') 'vhxc'
1473 else
1474 write(filename, fmt='(a,i1)') 'vhxc-sp', isp
1475 end if
1476
1477 call restart_read_mesh_function(restart, space, filename, mesh, hm%vhxc(:,isp), err)
1478 if (err /= 0) err2 = err2 + 1
1479
1480 end do
1481 if (err2 /= 0) ierr = ierr + 1
1482
1483 ! MGGAs and hybrid MGGAs have an extra term that also needs to be read
1484 err2 = 0
1485 if (family_is_mgga_with_exc(hm%xc)) then
1486 do isp = 1, hm%d%nspin
1487 if (hm%d%nspin == 1) then
1488 write(filename, fmt='(a)') 'vtau'
1489 else
1490 write(filename, fmt='(a,i1)') 'vtau-sp', isp
1491 end if
1492
1493 call restart_read_mesh_function(restart, space, filename, mesh, hm%vtau(:,isp), err)
1494 if (err /= 0) err2 = err2 + 1
1495
1496 end do
1497
1498 if (err2 /= 0) ierr = ierr + 2
1499 end if
1500
1501 if (debug%info) then
1502 message(1) = "Debug: Reading Vhxc restart done."
1503 call messages_info(1)
1504 end if
1505
1507 end subroutine hamiltonian_elec_load_vhxc
1508
1509 ! ---------------------------------------------------------
1514 subroutine hamiltonian_elec_update_with_ext_pot(this, mesh, space, ext_partners, time, mu)
1515 type(hamiltonian_elec_t), intent(inout) :: this
1516 class(space_t), intent(in) :: space
1517 class(mesh_t), intent(in) :: mesh
1518 type(partner_list_t), intent(in) :: ext_partners
1519 real(real64), intent(in) :: time(1:2)
1520 real(real64), intent(in) :: mu(1:2)
1521
1522 integer :: ispin, ip, idir, iatom, ilaser, itime
1523 real(real64) :: aa(space%dim), time_
1524 real(real64), allocatable :: vp(:,:)
1525 real(real64), allocatable :: velectric(:)
1526 type(lasers_t), pointer :: lasers
1527 type(gauge_field_t), pointer :: gfield
1528
1530 call profiling_in("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1531
1532 this%current_time = m_zero
1533 this%current_time = time(1)
1534
1535 ! set everything to zero
1536 call this%hm_base%clear(mesh%np)
1538 ! the xc, hartree and external potentials
1539 call this%hm_base%allocate_field(mesh, field_potential, &
1540 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1541
1542 do itime = 1, 2
1543 time_ = time(itime)
1544
1545 lasers => list_get_lasers(ext_partners)
1546 if(associated(lasers)) then
1547 do ilaser = 1, lasers%no_lasers
1548 select case (laser_kind(lasers%lasers(ilaser)))
1549 case (e_field_scalar_potential, e_field_electric)
1550 safe_allocate(velectric(1:mesh%np))
1551 do ispin = 1, this%d%spin_channels
1552 velectric = m_zero
1553 call laser_potential(lasers%lasers(ilaser), mesh, velectric, time_)
1554 !$omp parallel do simd schedule(static)
1555 do ip = 1, mesh%np
1556 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + mu(itime) * velectric(ip)
1557 end do
1558 end do
1559 safe_deallocate_a(velectric)
1560 case (e_field_magnetic)
1561 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, .false.)
1562 ! get the vector potential
1563 safe_allocate(vp(1:mesh%np, 1:space%dim))
1564 vp(1:mesh%np, 1:space%dim) = m_zero
1565 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1566 do idir = 1, space%dim
1567 !$omp parallel do schedule(static)
1568 do ip = 1, mesh%np
1569 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) &
1570 - mu(itime) * vp(ip, idir)/p_c
1571 end do
1572 end do
1573 ! and the magnetic field
1574 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
1575 safe_deallocate_a(vp)
1576 case (e_field_vector_potential)
1577 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1578 ! get the uniform vector potential associated with a magnetic field
1579 aa = m_zero
1580 call laser_field(lasers%lasers(ilaser), aa, time_)
1581 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) &
1582 - mu(itime) * aa/p_c
1583 end select
1584 end do
1585 end if
1586
1587 ! the gauge field
1588 gfield => list_get_gauge_field(ext_partners)
1589 if (associated(gfield)) then
1590 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1591 call gauge_field_get_vec_pot(gfield, aa)
1592 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1593 end if
1594
1595 ! the electric field for a periodic system through the gauge field
1596 ! TODO: The condition is wrong here: the e_field should be in non-periodic dims as E field
1597 ! and as a gauge field in the periodic dim, unless we use a Bery phase, in which, we do not use it
1598 ! this way. But this is unrelated to the gauge field
1599 if (allocated(this%ep%e_field) .and. associated(gfield)) then
1600 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1601 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1602 end if
1603
1604 end do
1605
1606 ! the vector potential of a static magnetic field
1607 if (allocated(this%ep%a_static)) then
1608 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1609 !ep%a_static contains 1/c A(r)
1610 !$omp parallel do schedule(static) private(idir)
1611 do ip = 1, mesh%np
1612 do idir = 1, space%dim
1613 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1614 end do
1615 end do
1616 end if
1617
1618 !The electric field is added to the KS potential
1619 if (family_is_mgga_with_exc(this%xc)) then
1620 call this%hm_base%accel_copy_pot(mesh, this%vtau)
1621 else
1622 call this%hm_base%accel_copy_pot(mesh)
1623 end if
1624
1625 ! and the static magnetic field
1626 if (allocated(this%ep%b_field)) then
1627 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1628 do idir = 1, 3
1629 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1630 end do
1631 end if
1632
1633 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1634
1635 call hamiltonian_elec_update_pot(this, mesh)
1636
1637 call build_phase()
1638
1639 call profiling_out("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1641
1642 contains
1643
1644 subroutine build_phase()
1645 integer :: ik, imat, nmat, max_npoints, offset, iphase, nphase
1646
1648
1649 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1650
1651 call profiling_in('UPDATE_PHASES')
1652 ! now regenerate the phases for the pseudopotentials
1653 do iatom = 1, this%ep%natoms
1654 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1655 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1656 end do
1657
1658 call profiling_out('UPDATE_PHASES')
1659 end if
1660
1661 if (allocated(this%hm_base%uniform_vector_potential)) then
1662 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1663 end if
1664
1665 max_npoints = this%vnl%max_npoints
1666 nmat = this%vnl%nprojector_matrices
1667
1668
1669 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1670
1671 nphase = 1
1672 if (this%der%boundaries%spiralBC) nphase = 3
1673
1674 if (.not. allocated(this%vnl%projector_phases)) then
1675 safe_allocate(this%vnl%projector_phases(1:max_npoints, nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1676 if (accel_is_enabled()) then
1677 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1678 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1679 end if
1680 end if
1681
1682 offset = 0
1683 do ik = this%d%kpt%start, this%d%kpt%end
1684 do imat = 1, this%vnl%nprojector_matrices
1685 iatom = this%vnl%projector_to_atom(imat)
1686 do iphase = 1, nphase
1687 !$omp parallel do schedule(static)
1688 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1689 this%vnl%projector_phases(ip, imat, iphase, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1690 end do
1691
1692 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1693 call accel_write_buffer(this%vnl%buff_projector_phases, &
1694 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1695 offset = offset)
1696 end if
1697 offset = offset + this%vnl%projector_matrices(imat)%npoints
1698 end do
1699 end do
1700 end do
1701
1702 end if
1703
1705 end subroutine build_phase
1706
1708
1709 ! ---------------------------------------------------------
1710 subroutine hamiltonian_elec_set_vhxc(hm, mesh, vold, vold_tau)
1711 type(hamiltonian_elec_t), intent(inout) :: hm
1712 class(mesh_t), intent(in) :: mesh
1713 real(real64), contiguous, intent(in) :: vold(:, :)
1714 real(real64), contiguous, optional, intent(in) :: vold_tau(:, :)
1715
1717
1718 call lalg_copy(mesh%np, hm%d%nspin, vold, hm%vhxc)
1719 if (present(vold_tau)) then
1720 call lalg_copy(mesh%np, hm%d%nspin, vold_tau, hm%vtau)
1721 end if
1722
1724 end subroutine hamiltonian_elec_set_vhxc
1725
1726 logical function hamiltonian_elec_needs_current(hm, states_are_real)
1727 type(hamiltonian_elec_t), intent(in) :: hm
1728 logical, intent(in) :: states_are_real
1729
1731
1732 if (hm%self_induced_magnetic) then
1733 if (.not. states_are_real) then
1735 else
1736 message(1) = 'No current density for real states since it is identically zero.'
1737 call messages_warning(1)
1738 end if
1739 end if
1740
1742
1743 ! ---------------------------------------------------------
1744 subroutine zhamiltonian_elec_apply_all(hm, namespace, mesh, st, hst)
1745 type(hamiltonian_elec_t), intent(inout) :: hm
1746 type(namespace_t), intent(in) :: namespace
1747 class(mesh_t), intent(in) :: mesh
1748 type(states_elec_t), intent(inout) :: st
1749 type(states_elec_t), intent(inout) :: hst
1750
1751 integer :: ik, ib, ist
1752 complex(real64), allocatable :: psi(:, :)
1753 complex(real64), allocatable :: psiall(:, :, :, :)
1754
1756
1757 do ik = st%d%kpt%start, st%d%kpt%end
1758 do ib = st%group%block_start, st%group%block_end
1759 call zhamiltonian_elec_apply_batch(hm, namespace, mesh, st%group%psib(ib, ik), hst%group%psib(ib, ik))
1760 end do
1761 end do
1762
1763 if (oct_exchange_enabled(hm%oct_exchange)) then
1764
1765 safe_allocate(psiall(mesh%np_part, 1:hst%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1766
1767 call states_elec_get_state(st, mesh, psiall)
1768
1769 call oct_exchange_prepare(hm%oct_exchange, mesh, psiall, hm%xc, hm%psolver, namespace)
1770
1771 safe_deallocate_a(psiall)
1772
1773 safe_allocate(psi(mesh%np_part, 1:hst%d%dim))
1774
1775 do ik = 1, st%nik
1776 do ist = 1, st%nst
1777 call states_elec_get_state(hst, mesh, ist, ik, psi)
1778 call oct_exchange_operator(hm%oct_exchange, namespace, mesh, psi, ist, ik)
1779 call states_elec_set_state(hst, mesh, ist, ik, psi)
1780 end do
1781 end do
1782
1783 safe_deallocate_a(psi)
1784
1785 end if
1786
1788 end subroutine zhamiltonian_elec_apply_all
1789
1790
1791 ! ---------------------------------------------------------
1792
1793 subroutine magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
1794 type(hamiltonian_elec_t), intent(in) :: hm
1795 type(namespace_t), intent(in) :: namespace
1796 class(mesh_t), intent(in) :: mesh
1797 complex(real64), intent(inout) :: psi(:,:)
1798 complex(real64), intent(out) :: hpsi(:,:)
1799 integer, intent(in) :: ik
1800 real(real64), intent(in) :: vmagnus(:, :, :)
1801 logical, optional, intent(in) :: set_phase
1802
1803 complex(real64), allocatable :: auxpsi(:, :), aux2psi(:, :)
1804 integer :: idim, ispin
1805
1806 push_sub(magnus)
1807
1808 ! We will assume, for the moment, no spinors.
1809 if (hm%d%dim /= 1) then
1810 call messages_not_implemented("Magnus with spinors", namespace=namespace)
1811 end if
1812
1813 safe_allocate( auxpsi(1:mesh%np_part, 1:hm%d%dim))
1814 safe_allocate(aux2psi(1:mesh%np, 1:hm%d%dim))
1815
1816 ispin = hm%d%get_spin_index(ik)
1817
1818 ! Compute (T + Vnl)|psi> and store it
1819 call zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, auxpsi, 1, ik, &
1820 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1821
1822 ! H|psi> = (T + Vnl)|psi> + Vpsl|psi> + Vmagnus(t2)|psi> + Vborders
1823 do idim = 1, hm%d%dim
1824 call lalg_copy(mesh%np, auxpsi(:, idim), hpsi(:, idim))
1825 hpsi(1:mesh%np, idim) = hpsi(1:mesh%np, idim) + hm%ep%Vpsl(1:mesh%np)*psi(1:mesh%np,idim)
1826 call vborders(mesh, hm, psi(:, idim), hpsi(:, idim))
1827 end do
1828 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + vmagnus(1:mesh%np, ispin, 2)*psi(1:mesh%np, 1)
1829
1830 ! Add first term of the commutator: - i Vmagnus(t1) (T + Vnl) |psi>
1831 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) - m_zi*vmagnus(1:mesh%np, ispin, 1)*auxpsi(1:mesh%np, 1)
1832
1833 ! Add second term of commutator: i (T + Vnl) Vmagnus(t1) |psi>
1834 auxpsi(1:mesh%np, 1) = vmagnus(1:mesh%np, ispin, 1)*psi(1:mesh%np, 1)
1835 call zhamiltonian_elec_apply_single(hm, namespace, mesh, auxpsi, aux2psi, 1, ik, &
1836 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1837 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + m_zi*aux2psi(1:mesh%np, 1)
1838
1839 safe_deallocate_a(auxpsi)
1840 safe_deallocate_a(aux2psi)
1841 pop_sub(magnus)
1842 end subroutine magnus
1843
1844 ! ---------------------------------------------------------
1845 subroutine vborders (mesh, hm, psi, hpsi)
1846 class(mesh_t), intent(in) :: mesh
1847 type(hamiltonian_elec_t), intent(in) :: hm
1848 complex(real64), intent(in) :: psi(:)
1849 complex(real64), intent(inout) :: hpsi(:)
1850
1851 integer :: ip
1852
1853 push_sub(vborders)
1854
1855 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
1856 do ip = 1, mesh%np
1857 hpsi(ip) = hpsi(ip) + m_zi*hm%abs_boundaries%mf(ip)*psi(ip)
1858 end do
1859 end if
1860
1861 pop_sub(vborders)
1862 end subroutine vborders
1863
1864 ! ---------------------------------------------------------
1865 logical function hamiltonian_elec_has_kick(hm)
1866 type(hamiltonian_elec_t), intent(in) :: hm
1867
1869
1870 hamiltonian_elec_has_kick = (abs(hm%kick%delta_strength) > m_epsilon)
1871
1873 end function hamiltonian_elec_has_kick
1874
1876 !
1877 subroutine hamiltonian_elec_set_mass(this, namespace, mass)
1878 class(hamiltonian_elec_t) , intent(inout) :: this
1879 type(namespace_t), intent(in) :: namespace
1880 real(real64), intent(in) :: mass
1881
1883
1884 if (parse_is_defined(namespace, 'ParticleMass')) then
1885 message(1) = 'Attempting to redefine a non-unit electron mass'
1886 call messages_fatal(1)
1887 else
1888 this%mass = mass
1889 end if
1890
1892 end subroutine hamiltonian_elec_set_mass
1893
1894 !----------------------------------------------------------
1901 subroutine hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
1902 type(hamiltonian_elec_t), intent(in) :: hm
1903 type(grid_t), intent(in) :: gr
1904 type(distributed_t), intent(in) :: kpt
1905 type(wfs_elec_t), intent(in) :: psib
1906 type(wfs_elec_t), intent(out) :: psib_with_phase
1907
1908 integer :: k_offset, n_boundary_points
1909
1911
1912 call psib%copy_to(psib_with_phase)
1913 if (hm%phase%is_allocated()) then
1914 call hm%phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.true.)
1915 ! apply phase correction while setting boundary -> memory needs to be
1916 ! accessed only once
1917 k_offset = psib%ik - kpt%start
1918 n_boundary_points = int(gr%np_part - gr%np)
1919 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = hm%phase%phase_corr(:, psib%ik), &
1920 buff_phase_corr = hm%phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.true.)
1921 else
1922 call psib%copy_data_to(gr%np, psib_with_phase)
1923 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
1924 end if
1925
1926 call psib_with_phase%do_pack(copy = .true.)
1927
1930
1931#include "undef.F90"
1932#include "real.F90"
1933#include "hamiltonian_elec_inc.F90"
1934
1935#include "undef.F90"
1936#include "complex.F90"
1937#include "hamiltonian_elec_inc.F90"
1939end module hamiltonian_elec_oct_m
1940
1941!! Local Variables:
1942!! mode: f90
1943!! coding: utf-8
1944!! End:
subroutine build_external_potentials()
subroutine build_phase()
subroutine external_potentials_checks()
subroutine build_interactions()
constant times a vector plus a vector
Definition: lalg_basic.F90:170
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:185
integer, parameter, public imaginary_absorbing
subroutine, public absorbing_boundaries_end(this)
subroutine, public absorbing_boundaries_init(this, namespace, space, gr)
pure logical function, public accel_allow_cpu_only()
Definition: accel.F90:410
subroutine, public accel_finish()
Definition: accel.F90:1296
pure logical function, public accel_is_enabled()
Definition: accel.F90:400
integer, parameter, public accel_mem_read_only
Definition: accel.F90:183
This module implements batches of mesh functions.
Definition: batch.F90:133
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:122
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64) function, public derivatives_lapl_get_max_eigenvalue(this)
Get maximum eigenvalue of discrete Laplacian. For the star and star_general stencils,...
logical function, public epot_have_external_potentials(ep)
Definition: epot.F90:609
integer, parameter, public scalar_relativistic_zora
Definition: epot.F90:166
subroutine, public epot_end(ep)
Definition: epot.F90:381
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:166
subroutine, public epot_init(ep, namespace, gr, ions, psolver, ispin, xc_family, kpoints)
Definition: epot.F90:218
subroutine, public epot_generate(ep, namespace, mesh, ions, st_d)
Definition: epot.F90:417
subroutine, public exchange_operator_init(this, namespace, space, st, der, mc, stencil, kpoints, omega, alpha, beta)
subroutine, public exchange_operator_end(this)
logical function, public list_has_gauge_field(partners)
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
logical function, public list_has_lasers(partners)
type(lasers_t) function, pointer, public list_get_lasers(partners)
integer, parameter, public external_pot_from_file
potential, defined in a file
subroutine, public load_external_potentials(external_potentials, namespace)
integer, parameter, public external_pot_charge_density
user-defined function for charge density
integer, parameter, public external_pot_usdef
user-defined function for local potential
integer, parameter, public external_pot_static_efield
Static electric field.
integer, parameter, public external_pot_static_bfield
Static magnetic field.
subroutine, public gauge_field_get_vec_pot(this, vec_pot)
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_epsilon
Definition: global.F90:203
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:223
real(real64), parameter, public m_one
Definition: global.F90:188
This module implements the underlying real-space grid.
Definition: grid.F90:117
This module defines an abstract class for Hamiltonians.
integer, parameter, public field_uniform_magnetic_field
integer, parameter, public field_uniform_vector_potential
integer, parameter, public field_vector_potential
integer, parameter, public field_potential
integer, parameter, public generalized_kohn_sham_dft
subroutine vborders(mesh, hm, psi, hpsi)
pure logical function, public hamiltonian_elec_apply_packed(this)
subroutine, public hamiltonian_elec_set_inh(hm, st)
subroutine, public zvmask(mesh, hm, st)
integer, parameter, public rdmft
subroutine, public zhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_adjoint(hm)
subroutine, public hamiltonian_elec_set_vhxc(hm, mesh, vold, vold_tau)
subroutine, public hamiltonian_elec_end(hm)
subroutine, public hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
Copy a batch to another batch and apply the Bloch phase to it.
subroutine, public zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
integer, parameter, public hartree
logical function, public hamiltonian_elec_has_kick(hm)
integer, parameter, public hartree_fock
integer, parameter, public independent_particles
subroutine, public magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
logical function hamiltonian_elec_hermitian(hm)
subroutine, public dhamiltonian_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)
real(real64) function, public hamiltonian_elec_get_time(this)
subroutine, public zhamiltonian_elec_apply_all(hm, namespace, mesh, st, hst)
subroutine, public hamiltonian_elec_dump_vhxc(restart, hm, space, mesh, ierr)
subroutine, public zhamiltonian_elec_diagonal(hm, mesh, diag, ik)
subroutine, public dvmask(mesh, hm, st)
logical function, public hamiltonian_elec_needs_current(hm, states_are_real)
subroutine, public hamiltonian_elec_remove_inh(hm)
subroutine zhamiltonian_elec_magnus_apply(hm, namespace, mesh, psib, hpsib, vmagnus)
subroutine, public zhamiltonian_elec_apply_atom(hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
subroutine, public hamiltonian_elec_update_pot(this, mesh, accumulate)
Update the KS potential of the electronic Hamiltonian.
integer, parameter, public velocity
subroutine dhamiltonian_elec_magnus_apply(hm, namespace, mesh, psib, hpsib, vmagnus)
subroutine hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
(re-)build the Hamiltonian for the next application:
subroutine hamiltonian_elec_span(hm, delta, emin, namespace)
subroutine, public hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, mc, kpoints, need_exchange, xc_photons)
subroutine dhamiltonian_elec_apply(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_load_vhxc(restart, hm, space, mesh, ierr)
pure logical function, public hamiltonian_elec_inh_term(hm)
subroutine hamiltonian_elec_set_mass(this, namespace, mass)
set the effective electron mass, checking whether it was previously redefined.
subroutine, public dhamiltonian_elec_diagonal(hm, mesh, diag, ik)
subroutine, public dhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
integer, parameter, public kohn_sham_dft
subroutine, public hamiltonian_elec_update_with_ext_pot(this, mesh, space, ext_partners, time, mu)
This is an extension of "hamiltonian_elec_update_pot" to be used by the CFM4 propagator....
subroutine, public hamiltonian_elec_not_adjoint(hm)
subroutine zhamiltonian_elec_apply(hm, namespace, mesh, psib, hpsib, terms, set_bc)
This module defines classes and functions for interaction partners.
Definition: io.F90:114
integer, parameter, public kick_magnon_mode
Definition: kick.F90:163
subroutine, public kick_end(kick)
Definition: kick.F90:795
subroutine, public kick_init(kick, namespace, space, kpoints, nspin)
Definition: kick.F90:223
pure integer function, public kick_get_type(kick)
Definition: kick.F90:1362
subroutine, public laser_vector_potential(laser, mesh, aa, time)
Definition: lasers.F90:1074
subroutine, public lasers_nondipole_laser_field_step(this, field, time)
Retrieves the NDSFA vector_potential correction. The nondipole field is obtained for consecutive time...
Definition: lasers.F90:1146
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:735
integer, parameter, public e_field_electric
Definition: lasers.F90:176
integer, parameter, public e_field_vector_potential
Definition: lasers.F90:176
subroutine, public laser_potential(laser, mesh, pot, time)
Definition: lasers.F90:1039
integer, parameter, public e_field_scalar_potential
Definition: lasers.F90:176
integer pure elemental function, public laser_kind(laser)
Definition: lasers.F90:711
subroutine, public laser_field(laser, field, time)
Retrieves the value of either the electric or the magnetic field. If the laser is given by a scalar p...
Definition: lasers.F90:1111
integer, parameter, public e_field_magnetic
Definition: lasers.F90:176
integer, parameter, public dft_u_none
Definition: lda_u.F90:200
subroutine, public lda_u_update_basis(this, space, gr, ions, st, psolver, namespace, kpoints, has_phase)
Definition: lda_u.F90:695
subroutine, public lda_u_build_phase_correction(this, space, std, boundaries, namespace, kpoints, vec_pot, vec_pot_var)
Build the phase correction to the global phase for all orbitals.
Definition: lda_u.F90:823
subroutine, public lda_u_end(this)
Definition: lda_u.F90:653
subroutine, public lda_u_init(this, namespace, space, level, gr, ions, st, mc, kpoints, has_phase)
Definition: lda_u.F90:280
This module implements fully polymorphic linked lists, and some specializations thereof.
integer, parameter, public constrain_none
subroutine, public magnetic_constrain_end(this)
subroutine, public magnetic_constrain_init(this, namespace, mesh, std, rho, natoms, min_dist)
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1125
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1097
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
subroutine, public mxll_coupling_init(this, d, gr, namespace, mass)
Parse variables and initialize Maxwell coupling.
subroutine, public set_electric_quadrupole_pot(this, mesh)
Computes the electric quadrupole potential where .
subroutine, public mxll_coupling_end(this)
Finalize and deallocate Maxwell coupling arrays.
subroutine, public mxll_coupling_calc(this, hm_base, mesh, d, space)
Add the Maxwell coupling to the electronic Hamiltonian.
logical function, public oct_exchange_enabled(this)
subroutine, public oct_exchange_remove(this)
Some general things and nomenclature:
Definition: par_vec.F90:171
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:502
subroutine, public pcm_calc_pot_rs(pcm, mesh, psolver, ions, v_h, v_ext, kick, time_present, kick_time)
Definition: pcm.F90:1215
subroutine, public pcm_end(pcm)
Definition: pcm.F90:3071
subroutine, public pcm_init(pcm, namespace, space, ions, grid, qtot, val_charge, external_potentials_present, kick_present)
Initializes the PCM calculation: reads the VdW molecular cavity and generates the PCM response matrix...
Definition: pcm.F90:294
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
Definition: poisson.F90:238
subroutine, public poisson_end(this)
Definition: poisson.F90:714
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
subroutine, public projector_init_phases(this, dim, std, bnd, kpoints, vec_pot, vec_pot_var)
Definition: projector.F90:264
subroutine, public scissor_end(this)
Definition: scissor.F90:239
subroutine, public states_set_complex(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_dim_copy(dout, din)
subroutine, public states_elec_dim_end(dim)
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
This module provides routines for communicating states when using states parallelization.
integer pure function, public symmetries_identity_index(this)
Definition: symmetries.F90:602
integer pure function, public symmetries_number(this)
Definition: symmetries.F90:556
type(type_t), public type_cmplx
Definition: types.F90:134
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
integer, parameter, public xc_oep_x_slater
Slater approximation to the exact exchange.
integer, parameter, public func_x
Definition: xc.F90:114
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:592
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:607
This module implements the "photon-free" electron-photon exchange-correlation functional.
Definition: xc_photons.F90:121
This module implements the ZORA terms for the Hamoiltonian.
Definition: zora.F90:116
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 abstract Hamiltonian class defines a skeleton for specific implementations.
abstract class for general interaction partners
Describes mesh distribution to nodes.
Definition: mesh.F90:186
Stores all communicators and groups.
Definition: multicomm.F90:206
The states_elec_t class contains all electronic wave functions.
This class described the 'photon-exchange' electron-photon xc functionals, based on QEDFT.
Definition: xc_photons.F90:156
This class is responsible for calculating and applying the ZORA.
Definition: zora.F90:145
int true(void)