49 use,
intrinsic :: iso_fortran_env
136 type(space_t),
private :: space
137 type(states_elec_dim_t) :: d
138 type(hamiltonian_elec_base_t) :: hm_base
139 type(phase_t) :: phase
140 type(energy_t),
allocatable :: energy
141 type(absorbing_boundaries_t) :: abs_boundaries
142 type(ks_potential_t) :: ks_pot
143 real(real64),
allocatable :: vberry(:,:)
145 type(derivatives_t),
pointer,
private :: der
147 type(nonlocal_pseudopotential_t) :: vnl
149 type(ions_t),
pointer :: ions
150 real(real64) :: exx_coef
152 type(poisson_t) :: psolver
155 logical :: self_induced_magnetic
156 real(real64),
allocatable :: a_ind(:, :)
157 real(real64),
allocatable :: b_ind(:, :)
159 integer :: theory_level
160 type(xc_t),
pointer :: xc
161 type(xc_photons_t),
pointer :: xc_photons
167 logical,
private :: adjoint
170 real(real64),
private :: mass
173 logical,
private :: inh_term
174 type(states_elec_t) :: inh_st
178 type(oct_exchange_t) :: oct_exchange
180 type(scissor_t) :: scissor
182 real(real64) :: current_time
183 logical,
private :: is_applied_packed
186 type(lda_u_t) :: lda_u
187 integer :: lda_u_level
189 logical,
public :: time_zero
191 type(exchange_operator_t),
public :: exxop
193 type(kpoints_t),
pointer,
public :: kpoints => null()
195 type(partner_list_t) :: external_potentials
196 real(real64),
allocatable,
public :: v_ext_pot(:)
197 real(real64),
allocatable,
public :: v_static(:)
199 type(ion_electron_local_potential_t) :: v_ie_loc
202 type(magnetic_constrain_t) :: magnetic_constrain
208 type(mxll_coupling_t) :: mxll
209 type(zora_t),
pointer :: zora => null()
224 integer,
public,
parameter :: &
233 mc, kpoints, need_exchange, xc_photons)
237 type(
grid_t),
target,
intent(inout) :: gr
238 type(
ions_t),
target,
intent(inout) :: ions
241 integer,
intent(in) :: theory_level
242 type(
xc_t),
target,
intent(in) :: xc
244 type(
kpoints_t),
target,
intent(in) :: kpoints
245 logical,
optional,
intent(in) :: need_exchange
246 type(
xc_photons_t),
optional,
target,
intent(in) :: xc_photons
249 logical :: need_exchange_
250 real(real64) :: rashba_coupling
257 hm%theory_level = theory_level
260 hm%kpoints => kpoints
286 if (space%dim /= 2)
then
287 write(
message(1),
'(a)')
'Rashba spin-orbit coupling can only be used for two-dimensional systems.'
293 call hm%hm_base%init(hm%d%nspin, hm%mass, rashba_coupling)
296 assert(
associated(gr%der%lapl))
297 hm%hm_base%kinetic => gr%der%lapl
299 safe_allocate(hm%energy)
306 if(
present(xc_photons))
then
307 hm%xc_photons => xc_photons
309 hm%xc_photons => null()
318 call poisson_init(hm%psolver, namespace, space, gr%der, mc, gr%stencil, st%qtot)
321 call epot_init(hm%ep, namespace, gr, hm%ions, hm%psolver, hm%d%ispin, hm%xc%family, hm%kpoints)
322 call kick_init(hm%kick, namespace, space, hm%kpoints, hm%d%ispin)
324 hm%zora =>
zora_t(namespace, hm%der, hm%d, hm%ep, hm%mass)
327 call hm%v_ie_loc%init(gr, hm%psolver, hm%ions, namespace)
329 call hm%nlcc%init(gr, hm%ions)
330 safe_allocate(st%rho_core(1:gr%np))
363 call parse_variable(namespace,
'CalculateSelfInducedMagneticField', .false., hm%self_induced_magnetic)
364 if (hm%self_induced_magnetic)
then
365 safe_allocate(hm%a_ind(1:gr%np_part, 1:space%dim))
366 safe_allocate(hm%b_ind(1:gr%np_part, 1:space%dim))
374 hm%inh_term = .false.
379 call hm%phase%init(gr, hm%d%kpt, hm%kpoints, st%d, space)
399 call lda_u_init(hm%lda_u, namespace, space, hm%lda_u_level, gr, ions, st, mc, &
400 hm%kpoints, hm%phase%is_allocated())
409 if(hm%lda_u_level /=
dft_u_none .and. hm%phase%is_allocated())
then
424 call parse_variable(namespace,
'HamiltonianApplyPacked', .
true., hm%is_applied_packed)
426 if (hm%theory_level ==
hartree_fock .and. st%parallel_in_states)
then
431 .and. st%parallel_in_states)
then
452 .or. hm%theory_level ==
rdmft .or. need_exchange_ .or. &
455 .or.
bitand(hm%xc%family, xc_family_oep) /= 0)
then
460 else if (
bitand(hm%xc%family, xc_family_oep) /= 0 .or. hm%theory_level ==
rdmft)
then
462 hm%kpoints, hm%xc%cam_omega, hm%xc%cam_alpha, hm%xc%cam_beta)
463 if (hm%theory_level ==
rdmft) hm%exxop%useACE = .false.
472 if (gr%use_curvilinear)
then
474 hm%is_applied_packed = .false.
475 call messages_write(
'Cannot use CUDA or OpenCL as curvilinear coordinates are used.')
478 call messages_write(
'Cannot use CUDA or OpenCL as curvilinear coordinates are used.', new_line = .
true.)
479 call messages_write(
'Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
509 if (
associated(hm%xc_photons))
then
510 if (hm%xc_photons%wants_to_renormalize_mass())
then
512 call hm%set_mass(namespace, hm%xc_photons%get_renormalized_mass())
525 class(*),
pointer :: potential
530 safe_allocate(hm%v_ext_pot(1:gr%np))
531 hm%v_ext_pot(1:gr%np) =
m_zero
533 call iter%start(hm%external_potentials)
534 do while (iter%has_next())
535 potential => iter%get_next()
536 select type (potential)
539 call potential%allocate_memory(gr)
540 call potential%calculate(namespace, gr, hm%psolver)
543 select case (potential%type)
548 if (.not.
allocated(hm%ep%b_field))
then
549 safe_allocate(hm%ep%b_field(1:3))
550 hm%ep%b_field(1:3) =
m_zero
552 hm%ep%b_field(1:3) = hm%ep%b_field(1:3) + potential%b_field(1:3)
554 if (.not.
allocated(hm%ep%a_static))
then
555 safe_allocate(hm%ep%a_static(1:gr%np, 1:space%dim))
556 hm%ep%a_static(1:gr%np, 1:space%dim) =
m_zero
558 call lalg_axpy(gr%np, space%dim,
m_one, potential%a_static, hm%ep%a_static)
561 if (.not.
allocated(hm%ep%e_field))
then
562 safe_allocate(hm%ep%e_field(1:space%dim))
563 hm%ep%e_field(1:space%dim) =
m_zero
565 hm%ep%e_field(1:space%dim) = hm%ep%e_field(1:space%dim) + potential%e_field(1:space%dim)
568 if (space%periodic_dim < space%dim)
then
569 if (.not.
allocated(hm%v_static))
then
570 safe_allocate(hm%v_static(1:gr%np))
571 hm%v_static(1:gr%np) =
m_zero
573 if (.not.
allocated(hm%ep%v_ext))
then
574 safe_allocate(hm%ep%v_ext(1:gr%np_part))
575 hm%ep%v_ext(1:gr%np_part) =
m_zero
581 if (hm%kpoints%use_symmetries)
then
585 message(1) =
"The StaticElectricField breaks (at least) one of the symmetries used to reduce the k-points."
586 message(2) =
"Set SymmetryBreakDir equal to StaticElectricField."
593 call potential%deallocate_memory()
606 class(*),
pointer :: potential
610 call iter%start(hm%external_potentials)
611 do while (iter%has_next())
612 potential => iter%get_next()
613 select type (potential)
617 message(1) =
"Applying StaticElectricField in a periodic direction is only accurate for large supercells."
618 message(2) =
"Single-point Berry phase is not appropriate when k-point sampling is needed."
634 logical :: external_potentials_present
635 logical :: kick_present
639 if (
allocated(hm%ep%e_field) .and. space%is_periodic() .and. .not.
list_has_gauge_field(ext_partners))
then
642 if (any(abs(hm%ep%e_field(1:space%periodic_dim)) >
m_epsilon))
then
643 safe_allocate(hm%vberry(1:gr%np, 1:hm%d%nspin))
654 call pcm_init(hm%pcm, namespace, space, ions, gr, st%qtot, st%val_charge, external_potentials_present, kick_present)
655 if (hm%pcm%run_pcm)
then
676 call hm%hm_base%end()
682 safe_deallocate_a(hm%vberry)
683 safe_deallocate_a(hm%a_ind)
684 safe_deallocate_a(hm%b_ind)
685 safe_deallocate_a(hm%v_ext_pot)
687 safe_deallocate_p(hm%zora)
706 safe_deallocate_a(hm%energy)
708 if (hm%pcm%run_pcm)
call pcm_end(hm%pcm)
710 call hm%v_ie_loc%end()
713 call iter%start(hm%external_potentials)
714 do while (iter%has_next())
715 potential => iter%get_next()
716 safe_deallocate_p(potential)
718 call hm%external_potentials%empty()
719 safe_deallocate_a(hm%v_static)
745 integer,
intent(in) :: terms
766 real(real64),
intent(in) ::
delta(:)
767 real(real64),
intent(in) :: emin
778 hm%spectral_middle_point = (emax + emin) /
m_two
779 hm%spectral_half_span = (emax - emin) /
m_two
814 if (hm%inh_term)
then
816 hm%inh_term = .false.
828 if (.not. hm%adjoint)
then
831 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
848 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
860 class(
mesh_t),
intent(in) :: mesh
862 class(
space_t),
intent(in) :: space
864 real(real64),
optional,
intent(in) :: time
866 integer :: ispin, ip, idir, iatom, ilaser
867 real(real64) :: aa(space%dim), time_
868 real(real64),
allocatable :: vp(:,:)
871 real(real64) :: am(space%dim)
876 this%current_time =
m_zero
877 if (
present(time)) this%current_time = time
882 call this%hm_base%clear(mesh%np)
889 if (
present(time) .or. this%time_zero)
then
892 if(
associated(lasers))
then
893 do ilaser = 1, lasers%no_lasers
894 select case (
laser_kind(lasers%lasers(ilaser)))
896 do ispin = 1, this%d%spin_channels
898 this%hm_base%potential(:, ispin), time_)
904 safe_allocate(vp(1:mesh%np, 1:space%dim))
905 vp(1:mesh%np, 1:space%dim) =
m_zero
909 do idir = 1, space%dim
910 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + vp(ip, idir)/
p_c
914 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
915 safe_deallocate_a(vp)
921 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/
p_c
926 assert(
allocated(this%hm_base%uniform_vector_potential))
928 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - am/
p_c
934 if (
associated(gfield))
then
937 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/
p_c
941 if (
allocated(this%ep%e_field) .and.
associated(gfield))
then
942 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
943 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
947 if (
associated(this%xc_photons))
then
948 if(this%xc_photons%lpfmf .and.
allocated(this%xc_photons%mf_vector_potential))
then
951 this%hm_base%uniform_vector_potential(1:space%dim) = &
952 this%hm_base%uniform_vector_potential(1:space%dim) - this%xc_photons%mf_vector_potential(1:space%dim)/
p_c
959 if (
allocated(this%ep%a_static))
then
964 do idir = 1, space%dim
965 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
974 call this%hm_base%accel_copy_pot(mesh)
977 if (
allocated(this%ep%b_field))
then
980 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
985 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
990 if (this%mxll%test_equad)
then
1002 integer :: ik, imat, nmat, max_npoints, offset
1004 integer :: iphase, nphase
1008 if ((.not. this%kpoints%gamma_only()) .or.
allocated(this%hm_base%uniform_vector_potential))
then
1012 do iatom = 1, this%ep%natoms
1013 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1014 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1020 if (
allocated(this%hm_base%uniform_vector_potential))
then
1022 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1027 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1031 max_npoints = this%vnl%max_npoints
1032 nmat = this%vnl%nprojector_matrices
1035 if (this%phase%is_allocated() .and.
allocated(this%vnl%projector_matrices))
then
1038 if (this%der%boundaries%spiralBC) nphase = 3
1040 if (.not.
allocated(this%vnl%projector_phases))
then
1041 safe_allocate(this%vnl%projector_phases(1:max_npoints, 1:nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1044 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1047 this%vnl%nphase = nphase
1052 do ik = this%d%kpt%start, this%d%kpt%end
1053 do imat = 1, this%vnl%nprojector_matrices
1054 iatom = this%vnl%projector_to_atom(imat)
1055 do iphase = 1, nphase
1057 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1058 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1061 if (
accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0)
then
1063 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1064 offset = offset, async=.
true.)
1066 offset = offset + this%vnl%projector_matrices(imat)%npoints
1087 class(
mesh_t),
intent(in) :: mesh
1088 logical,
optional,
intent(in) :: accumulate
1090 integer :: ispin, ip
1097 do ispin = 1, this%d%nspin
1100 this%hm_base%potential(ip, ispin) =
m_zero
1107 do ispin = 1, this%d%nspin
1108 if (ispin <= 2)
then
1112 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%ep%vpsl(ip) + this%v_ext_pot(ip)
1116 if (this%pcm%run_pcm)
then
1117 if (this%pcm%solute)
then
1120 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1121 this%pcm%v_e_rs(ip) + this%pcm%v_n_rs(ip)
1125 if (this%pcm%localf)
then
1128 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1129 this%pcm%v_ext_rs(ip)
1139 this%hm_base%Impotential(ip, ispin) = this%hm_base%Impotential(ip, ispin) + this%abs_boundaries%mf(ip)
1150 call this%zora%update(this%der, this%hm_base%potential)
1154 do ispin = 1, this%d%nspin
1156 if (
allocated(this%hm_base%zeeman_pot))
then
1159 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%hm_base%zeeman_pot(ip, ispin)
1165 if (this%mxll%test_equad)
then
1168 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%mxll%e_quadrupole_pot(ip)
1177 call this%ks_pot%add_vhxc(this%hm_base%potential)
1179 call this%hm_base%accel_copy_pot(mesh)
1189 type(
grid_t),
intent(in) :: gr
1190 type(
ions_t),
target,
intent(inout) :: ions
1193 real(real64),
optional,
intent(in) :: time
1198 call epot_generate(this%ep, namespace, gr, this%ions, this%d)
1203 if (
allocated(this%ep%e_field) .and. space%periodic_dim < space%dim)
then
1209 this%v_ie_loc%atoms_dist => ions%atoms_dist
1210 this%v_ie_loc%atom => ions%atom
1211 call this%v_ie_loc%calculate()
1214 call lalg_axpy(gr%np,
m_one, this%v_ie_loc%potential(:,1), this%ep%vpsl)
1218 if (this%ep%nlcc)
then
1219 this%nlcc%atoms_dist => ions%atoms_dist
1220 this%nlcc%atom => ions%atom
1221 call this%nlcc%calculate()
1222 call lalg_copy(gr%np, this%nlcc%density(:,1), st%rho_core)
1225 call this%vnl%build(space, gr, this%ep)
1230 if (this%ep%non_local .and. .not. this%vnl%apply_projector_matrices)
then
1232 call messages_write(
'Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.')
1235 call messages_write(
'Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.',&
1237 call messages_write(
'Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
1244 if (this%pcm%run_pcm)
then
1247 if (this%pcm%solute)
then
1254 if (this%pcm%localf .and.
allocated(this%v_static))
then
1255 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, v_ext = this%ep%v_ext(1:gr%np_part))
1260 call lda_u_update_basis(this%lda_u, space, gr, ions, st, this%psolver, namespace, this%kpoints, &
1261 this%phase%is_allocated())
1271 time = this%current_time
1279 apply = this%is_applied_packed
1287 type(namespace_t),
intent(in) :: namespace
1288 class(space_t),
intent(in) :: space
1289 type(lattice_vectors_t),
intent(in) :: latt
1290 class(species_t),
intent(in) :: species
1291 real(real64),
intent(in) :: pos(1:space%dim)
1292 integer,
intent(in) :: ia
1293 class(mesh_t),
intent(in) :: mesh
1294 complex(real64),
intent(in) :: psi(:,:)
1295 complex(real64),
intent(out) :: vpsi(:,:)
1298 real(real64),
allocatable :: vlocal(:)
1301 safe_allocate(vlocal(1:mesh%np_part))
1303 call epot_local_potential(hm%ep, namespace, space, latt, mesh, species, pos, ia, vlocal)
1305 do idim = 1, hm%d%dim
1306 vpsi(1:mesh%np, idim) = vlocal(1:mesh%np) * psi(1:mesh%np, idim)
1309 safe_deallocate_a(vlocal)
1320 class(space_t),
intent(in) :: space
1321 class(mesh_t),
intent(in) :: mesh
1322 type(partner_list_t),
intent(in) :: ext_partners
1323 real(real64),
intent(in) :: time(1:2)
1324 real(real64),
intent(in) :: mu(1:2)
1326 integer :: ispin, ip, idir, iatom, ilaser, itime
1327 real(real64) :: aa(space%dim), time_
1328 real(real64),
allocatable :: vp(:,:)
1329 real(real64),
allocatable :: velectric(:)
1330 type(lasers_t),
pointer :: lasers
1331 type(gauge_field_t),
pointer :: gfield
1334 call profiling_in(
"HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1336 this%current_time = m_zero
1337 this%current_time = time(1)
1340 call this%hm_base%clear(mesh%np)
1343 call this%hm_base%allocate_field(mesh, field_potential, &
1344 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1349 lasers => list_get_lasers(ext_partners)
1350 if(
associated(lasers))
then
1351 do ilaser = 1, lasers%no_lasers
1352 select case (laser_kind(lasers%lasers(ilaser)))
1353 case (e_field_scalar_potential, e_field_electric)
1354 safe_allocate(velectric(1:mesh%np))
1355 do ispin = 1, this%d%spin_channels
1357 call laser_potential(lasers%lasers(ilaser), mesh, velectric, time_)
1360 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + mu(itime) * velectric(ip)
1363 safe_deallocate_a(velectric)
1364 case (e_field_magnetic)
1365 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, .false.)
1367 safe_allocate(vp(1:mesh%np, 1:space%dim))
1368 vp(1:mesh%np, 1:space%dim) = m_zero
1369 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1370 do idir = 1, space%dim
1373 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) &
1374 - mu(itime) * vp(ip, idir)/p_c
1378 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
1379 safe_deallocate_a(vp)
1380 case (e_field_vector_potential)
1381 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1384 call laser_field(lasers%lasers(ilaser), aa, time_)
1385 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) &
1386 - mu(itime) * aa/p_c
1392 gfield => list_get_gauge_field(ext_partners)
1393 if (
associated(gfield))
then
1394 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1395 call gauge_field_get_vec_pot(gfield, aa)
1396 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1403 if (
allocated(this%ep%e_field) .and.
associated(gfield))
then
1404 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1405 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1411 if (
allocated(this%ep%a_static))
then
1412 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1416 do idir = 1, space%dim
1417 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1423 call this%hm_base%accel_copy_pot(mesh)
1426 if (
allocated(this%ep%b_field))
then
1427 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1429 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1433 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1439 call profiling_out(
"HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1445 integer :: ik, imat, nmat, max_npoints, offset, iphase, nphase
1449 if ((.not. this%kpoints%gamma_only()) .or.
allocated(this%hm_base%uniform_vector_potential))
then
1451 call profiling_in(
'UPDATE_PHASES')
1453 do iatom = 1, this%ep%natoms
1454 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1455 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1458 call profiling_out(
'UPDATE_PHASES')
1461 if (
allocated(this%hm_base%uniform_vector_potential))
then
1462 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1465 max_npoints = this%vnl%max_npoints
1466 nmat = this%vnl%nprojector_matrices
1469 if (this%phase%is_allocated() .and.
allocated(this%vnl%projector_matrices))
then
1472 if (this%der%boundaries%spiralBC) nphase = 3
1474 if (.not.
allocated(this%vnl%projector_phases))
then
1475 safe_allocate(this%vnl%projector_phases(1:max_npoints, nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1476 if (accel_is_enabled())
then
1477 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1478 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1483 do ik = this%d%kpt%start, this%d%kpt%end
1484 do imat = 1, this%vnl%nprojector_matrices
1485 iatom = this%vnl%projector_to_atom(imat)
1486 do iphase = 1, nphase
1488 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1489 this%vnl%projector_phases(ip, imat, iphase, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1492 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0)
then
1493 call accel_write_buffer(this%vnl%buff_projector_phases, &
1494 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1497 offset = offset + this%vnl%projector_matrices(imat)%npoints
1511 logical,
intent(in) :: states_are_real
1515 if (hm%self_induced_magnetic)
then
1516 if (.not. states_are_real)
then
1519 message(1) =
'No current density for real states since it is identically zero.'
1520 call messages_warning(1)
1529 type(namespace_t),
intent(in) :: namespace
1530 class(mesh_t),
intent(in) :: mesh
1531 type(states_elec_t),
intent(inout) :: st
1532 type(states_elec_t),
intent(inout) :: hst
1534 integer :: ik, ib, ist
1535 complex(real64),
allocatable :: psi(:, :)
1536 complex(real64),
allocatable :: psiall(:, :, :, :)
1540 do ik = st%d%kpt%start, st%d%kpt%end
1541 do ib = st%group%block_start, st%group%block_end
1546 if (oct_exchange_enabled(hm%oct_exchange))
then
1548 safe_allocate(psiall(mesh%np_part, 1:hst%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1550 call states_elec_get_state(st, mesh, psiall)
1552 call oct_exchange_prepare(hm%oct_exchange, mesh, psiall, hm%xc, hm%psolver, namespace)
1554 safe_deallocate_a(psiall)
1556 safe_allocate(psi(mesh%np_part, 1:hst%d%dim))
1560 call states_elec_get_state(hst, mesh, ist, ik, psi)
1561 call oct_exchange_operator(hm%oct_exchange, namespace, mesh, psi, ist, ik)
1562 call states_elec_set_state(hst, mesh, ist, ik, psi)
1566 safe_deallocate_a(psi)
1576 subroutine magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
1578 type(namespace_t),
intent(in) :: namespace
1579 class(mesh_t),
intent(in) :: mesh
1580 complex(real64),
contiguous,
intent(inout) :: psi(:,:)
1581 complex(real64),
contiguous,
intent(out) :: hpsi(:,:)
1582 integer,
intent(in) :: ik
1583 real(real64),
intent(in) :: vmagnus(:, :, :)
1584 logical,
optional,
intent(in) :: set_phase
1586 complex(real64),
allocatable :: auxpsi(:, :), aux2psi(:, :)
1587 integer :: idim, ispin
1592 if (hm%d%dim /= 1)
then
1593 call messages_not_implemented(
"Magnus with spinors", namespace=namespace)
1596 safe_allocate( auxpsi(1:mesh%np_part, 1:hm%d%dim))
1597 safe_allocate(aux2psi(1:mesh%np, 1:hm%d%dim))
1599 ispin = hm%d%get_spin_index(ik)
1603 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1606 do idim = 1, hm%d%dim
1607 call lalg_copy(mesh%np, auxpsi(:, idim), hpsi(:, idim))
1608 hpsi(1:mesh%np, idim) = hpsi(1:mesh%np, idim) + hm%ep%Vpsl(1:mesh%np)*psi(1:mesh%np,idim)
1609 call vborders(mesh, hm, psi(:, idim), hpsi(:, idim))
1611 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + vmagnus(1:mesh%np, ispin, 2)*psi(1:mesh%np, 1)
1614 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) - m_zi*vmagnus(1:mesh%np, ispin, 1)*auxpsi(1:mesh%np, 1)
1617 auxpsi(1:mesh%np, 1) = vmagnus(1:mesh%np, ispin, 1)*psi(1:mesh%np, 1)
1619 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1620 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + m_zi*aux2psi(1:mesh%np, 1)
1622 safe_deallocate_a(auxpsi)
1623 safe_deallocate_a(aux2psi)
1628 subroutine vborders (mesh, hm, psi, hpsi)
1629 class(mesh_t),
intent(in) :: mesh
1631 complex(real64),
intent(in) :: psi(:)
1632 complex(real64),
intent(inout) :: hpsi(:)
1638 if (hm%abs_boundaries%abtype == imaginary_absorbing)
then
1640 hpsi(ip) = hpsi(ip) + m_zi*hm%abs_boundaries%mf(ip)*psi(ip)
1662 type(namespace_t),
intent(in) :: namespace
1663 real(real64),
intent(in) :: mass
1667 if (parse_is_defined(namespace,
'ParticleMass'))
then
1668 message(1) =
'Attempting to redefine a non-unit electron mass'
1669 call messages_fatal(1)
1686 type(grid_t),
intent(in) :: gr
1687 type(distributed_t),
intent(in) :: kpt
1688 type(wfs_elec_t),
intent(in) :: psib
1689 type(wfs_elec_t),
intent(out) :: psib_with_phase
1691 integer :: k_offset, n_boundary_points
1695 call psib%copy_to(psib_with_phase)
1696 if (hm%phase%is_allocated())
then
1697 call hm%phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.
true.)
1700 k_offset = psib%ik - kpt%start
1701 n_boundary_points = int(gr%np_part - gr%np)
1702 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = hm%phase%phase_corr(:, psib%ik), &
1703 buff_phase_corr = hm%phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.
true.)
1705 call psib%copy_data_to(gr%np, psib_with_phase)
1706 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
1709 call psib_with_phase%do_pack(copy = .
true.)
1717 class(mesh_t),
intent(in) :: mesh
1718 real(real64),
contiguous,
intent(out) :: diag(:,:)
1719 integer,
intent(in) :: ik
1721 integer :: idim, ip, ispin
1723 real(real64),
allocatable :: ldiag(:)
1727 safe_allocate(ldiag(1:mesh%np))
1731 call derivatives_lapl_diag(hm%der, ldiag)
1733 do idim = 1, hm%d%dim
1734 diag(1:mesh%np, idim) = -m_half/hm%mass*ldiag(1:mesh%np)
1737 select case (hm%d%ispin)
1739 case (unpolarized, spin_polarized)
1740 ispin = hm%d%get_spin_index(ik)
1741 diag(1:mesh%np, 1) = diag(1:mesh%np, 1) + hm%ep%vpsl(1:mesh%np)
1745 diag(ip, 1) = diag(ip, 1) + hm%ep%vpsl(ip)
1746 diag(ip, 2) = diag(ip, 2) + hm%ep%vpsl(ip)
1751 call hm%ks_pot%add_vhxc(diag)
1760#include "hamiltonian_elec_inc.F90"
1763#include "complex.F90"
1764#include "hamiltonian_elec_inc.F90"
subroutine build_external_potentials()
subroutine external_potentials_checks()
subroutine build_interactions()
constant times a vector plus a vector
Copies a vector x, to a vector y.
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()
subroutine, public accel_finish()
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
Module implementing boundary conditions in Octopus.
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)
integer, parameter, public scalar_relativistic_zora
subroutine, public epot_end(ep)
integer, parameter, public fully_relativistic_zora
subroutine, public epot_init(ep, namespace, gr, ions, psolver, ispin, xc_family, kpoints)
subroutine, public epot_generate(ep, namespace, mesh, ions, st_d)
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
real(real64), parameter, public m_zero
real(real64), parameter, public m_epsilon
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
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 term_mgga
integer, parameter, public field_potential
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)
subroutine, public zhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_adjoint(hm)
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)
pure logical function hamiltonian_elec_needs_mgga_term(hm, terms)
logical function, public hamiltonian_elec_has_kick(hm)
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 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_diagonal(hm, mesh, diag, ik)
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)
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_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
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.
integer, parameter, public kick_magnon_mode
subroutine, public kick_end(kick)
subroutine, public kick_init(kick, namespace, space, kpoints, nspin)
pure integer function, public kick_get_type(kick)
A module to handle KS potential, without the external potential.
integer, parameter, public rdmft
integer, parameter, public hartree
integer, parameter, public hartree_fock
integer, parameter, public independent_particles
integer, parameter, public generalized_kohn_sham_dft
integer, parameter, public kohn_sham_dft
subroutine, public laser_vector_potential(laser, mesh, aa, time)
subroutine, public lasers_nondipole_laser_field_step(this, field, time)
Retrieves the NDSFA vector_potential correction. The nondipole field is obtained for consecutive time...
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
integer, parameter, public e_field_electric
integer, parameter, public e_field_vector_potential
subroutine, public laser_potential(laser, mesh, pot, time)
integer, parameter, public e_field_scalar_potential
integer pure elemental function, public laser_kind(laser)
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...
integer, parameter, public e_field_magnetic
integer, parameter, public dft_u_none
subroutine, public lda_u_update_basis(this, space, gr, ions, st, psolver, namespace, kpoints, has_phase)
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.
subroutine, public lda_u_end(this)
subroutine, public lda_u_init(this, namespace, space, level, gr, ions, st, mc, kpoints, has_phase)
This module implements fully polymorphic linked lists, and some specializations thereof.
This modules implements the routines for doing constrain DFT for noncollinear magnetism.
subroutine, public magnetic_constrain_end(this)
Releases memory of the magnetic constrain.
subroutine, public magnetic_constrain_init(this, namespace, mesh, std, natoms, min_dist)
Initilializes the magnetic_constrain_t object.
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_experimental(name, namespace)
This module handles the communicators for the various parallelization strategies.
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)
this module contains the low-level part of the output system
Some general things and nomenclature:
logical function, public parse_is_defined(namespace, name)
subroutine, public pcm_calc_pot_rs(pcm, mesh, psolver, ions, v_h, v_ext, kick, time_present, kick_time)
subroutine, public pcm_end(pcm)
real(real64), dimension(:,:), allocatable delta
D_E matrix in JCP 139, 024105 (2013).
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...
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
subroutine, public poisson_end(this)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine, public projector_init_phases(this, dim, std, bnd, kpoints, vec_pot, vec_pot_var)
subroutine, public scissor_end(this)
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)
integer pure function, public symmetries_number(this)
type(type_t), public type_cmplx
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
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
logical pure function, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
This module implements the "photon-free" electron-photon exchange-correlation functional.
This module implements the ZORA terms for the Hamoiltonian.
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
The abstract Hamiltonian class defines a skeleton for specific implementations.
abstract class for general interaction partners
iterator for the list of partners
Describes mesh distribution to nodes.
Stores all communicators and groups.
The states_elec_t class contains all electronic wave functions.
This class described the 'photon-exchange' electron-photon xc functionals, based on QEDFT.
This class is responsible for calculating and applying the ZORA.