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()
223 integer,
public,
parameter :: &
232 mc, kpoints, need_exchange, xc_photons)
236 type(
grid_t),
target,
intent(inout) :: gr
237 type(
ions_t),
target,
intent(inout) :: ions
240 integer,
intent(in) :: theory_level
241 type(
xc_t),
target,
intent(in) :: xc
244 logical,
optional,
intent(in) :: need_exchange
248 logical :: need_exchange_
249 real(real64) :: rashba_coupling
256 hm%theory_level = theory_level
259 hm%kpoints => kpoints
285 if (space%dim /= 2)
then
286 write(
message(1),
'(a)')
'Rashba spin-orbit coupling can only be used for two-dimensional systems.'
292 call hm%hm_base%init(hm%d%nspin, hm%mass, rashba_coupling)
295 assert(
associated(gr%der%lapl))
296 hm%hm_base%kinetic => gr%der%lapl
298 safe_allocate(hm%energy)
305 if(
present(xc_photons))
then
306 hm%xc_photons => xc_photons
308 hm%xc_photons => null()
317 call poisson_init(hm%psolver, namespace, space, gr%der, mc, gr%stencil, st%qtot)
320 call epot_init(hm%ep, namespace, gr, hm%ions, hm%psolver, hm%d%ispin, hm%xc%family, hm%kpoints)
321 call kick_init(hm%kick, namespace, space, hm%kpoints, hm%d%ispin)
323 hm%zora =>
zora_t(namespace, hm%der, hm%d, hm%ep, hm%mass)
326 call hm%v_ie_loc%init(gr, hm%psolver, hm%ions, namespace)
328 call hm%nlcc%init(gr, hm%ions)
329 safe_allocate(st%rho_core(1:gr%np))
362 call parse_variable(namespace,
'CalculateSelfInducedMagneticField', .false., hm%self_induced_magnetic)
363 if (hm%self_induced_magnetic)
then
364 safe_allocate(hm%a_ind(1:gr%np_part, 1:space%dim))
365 safe_allocate(hm%b_ind(1:gr%np_part, 1:space%dim))
373 hm%inh_term = .false.
378 call hm%phase%init(gr, hm%d%kpt, hm%kpoints, st%d, space)
398 call lda_u_init(hm%lda_u, namespace, space, hm%lda_u_level, gr, ions, st, mc, &
399 hm%kpoints, hm%phase%is_allocated())
408 if(hm%lda_u_level /=
dft_u_none .and. hm%phase%is_allocated())
then
423 call parse_variable(namespace,
'HamiltonianApplyPacked', .
true., hm%is_applied_packed)
425 if (hm%theory_level ==
hartree_fock .and. st%parallel_in_states)
then
430 .and. st%parallel_in_states)
then
451 .or. hm%theory_level ==
rdmft .or. need_exchange_ .or. &
454 .or.
bitand(hm%xc%family, xc_family_oep) /= 0)
then
459 else if (
bitand(hm%xc%family, xc_family_oep) /= 0 .or. hm%theory_level ==
rdmft)
then
461 hm%kpoints, hm%xc%cam_omega, hm%xc%cam_alpha, hm%xc%cam_beta)
462 if (hm%theory_level ==
rdmft) hm%exxop%useACE = .false.
471 if (gr%use_curvilinear)
then
473 hm%is_applied_packed = .false.
474 call messages_write(
'Cannot use CUDA or OpenCL as curvilinear coordinates are used.')
477 call messages_write(
'Cannot use CUDA or OpenCL as curvilinear coordinates are used.', new_line = .
true.)
478 call messages_write(
'Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
508 if (
associated(hm%xc_photons))
then
509 if (hm%xc_photons%wants_to_renormalize_mass())
then
511 call hm%set_mass(namespace, hm%xc_photons%get_renormalized_mass())
524 class(*),
pointer :: potential
529 safe_allocate(hm%v_ext_pot(1:gr%np))
530 hm%v_ext_pot(1:gr%np) =
m_zero
532 call iter%start(hm%external_potentials)
533 do while (iter%has_next())
534 potential => iter%get_next()
535 select type (potential)
538 call potential%allocate_memory(gr)
539 call potential%calculate(namespace, gr, hm%psolver)
542 select case (potential%type)
548 message(1) =
"Cannot use static magnetic field with real wavefunctions"
552 if (.not.
allocated(hm%ep%b_field))
then
553 safe_allocate(hm%ep%b_field(1:3))
554 hm%ep%b_field(1:3) =
m_zero
556 hm%ep%b_field(1:3) = hm%ep%b_field(1:3) + potential%b_field(1:3)
558 if (.not.
allocated(hm%ep%a_static))
then
559 safe_allocate(hm%ep%a_static(1:gr%np, 1:space%dim))
560 hm%ep%a_static(1:gr%np, 1:space%dim) =
m_zero
562 call lalg_axpy(gr%np, space%dim,
m_one, potential%a_static, hm%ep%a_static)
565 if (.not.
allocated(hm%ep%e_field))
then
566 safe_allocate(hm%ep%e_field(1:space%dim))
567 hm%ep%e_field(1:space%dim) =
m_zero
569 hm%ep%e_field(1:space%dim) = hm%ep%e_field(1:space%dim) + potential%e_field(1:space%dim)
572 if (space%periodic_dim < space%dim)
then
573 if (.not.
allocated(hm%v_static))
then
574 safe_allocate(hm%v_static(1:gr%np))
575 hm%v_static(1:gr%np) =
m_zero
577 if (.not.
allocated(hm%ep%v_ext))
then
578 safe_allocate(hm%ep%v_ext(1:gr%np_part))
579 hm%ep%v_ext(1:gr%np_part) =
m_zero
585 if (hm%kpoints%use_symmetries)
then
589 message(1) =
"The StaticElectricField breaks (at least) one of the symmetries used to reduce the k-points."
590 message(2) =
"Set SymmetryBreakDir equal to StaticElectricField."
597 call potential%deallocate_memory()
610 class(*),
pointer :: potential
614 call iter%start(hm%external_potentials)
615 do while (iter%has_next())
616 potential => iter%get_next()
617 select type (potential)
621 message(1) =
"Applying StaticElectricField in a periodic direction is only accurate for large supercells."
622 message(2) =
"Single-point Berry phase is not appropriate when k-point sampling is needed."
638 logical :: external_potentials_present
639 logical :: kick_present
643 if (
allocated(hm%ep%e_field) .and. space%is_periodic() .and. .not.
list_has_gauge_field(ext_partners))
then
646 if (any(abs(hm%ep%e_field(1:space%periodic_dim)) >
m_epsilon))
then
647 safe_allocate(hm%vberry(1:gr%np, 1:hm%d%nspin))
658 call pcm_init(hm%pcm, namespace, space, ions, gr, st%qtot, st%val_charge, external_potentials_present, kick_present)
659 if (hm%pcm%run_pcm)
then
680 call hm%hm_base%end()
686 safe_deallocate_a(hm%vberry)
687 safe_deallocate_a(hm%a_ind)
688 safe_deallocate_a(hm%b_ind)
689 safe_deallocate_a(hm%v_ext_pot)
691 safe_deallocate_p(hm%zora)
710 safe_deallocate_a(hm%energy)
712 if (hm%pcm%run_pcm)
call pcm_end(hm%pcm)
714 call hm%v_ie_loc%end()
717 call iter%start(hm%external_potentials)
718 do while (iter%has_next())
719 potential => iter%get_next()
720 safe_deallocate_p(potential)
722 call hm%external_potentials%empty()
723 safe_deallocate_a(hm%v_static)
749 real(real64),
intent(in) :: delta(:)
750 real(real64),
intent(in) :: emin
761 hm%spectral_middle_point = (emax + emin) /
m_two
762 hm%spectral_half_span = (emax - emin) /
m_two
797 if (hm%inh_term)
then
799 hm%inh_term = .false.
811 if (.not. hm%adjoint)
then
814 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
831 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
843 class(
mesh_t),
intent(in) :: mesh
845 class(
space_t),
intent(in) :: space
847 real(real64),
optional,
intent(in) :: time
849 integer :: ispin, ip, idir, iatom, ilaser
850 real(real64) :: aa(space%dim), time_
851 real(real64),
allocatable :: vp(:,:)
854 real(real64) :: am(space%dim)
859 this%current_time =
m_zero
860 if (
present(time)) this%current_time = time
865 call this%hm_base%clear(mesh%np)
872 if (
present(time) .or. this%time_zero)
then
875 if(
associated(lasers))
then
876 do ilaser = 1, lasers%no_lasers
877 select case (
laser_kind(lasers%lasers(ilaser)))
879 do ispin = 1, this%d%spin_channels
881 this%hm_base%potential(:, ispin), time_)
887 safe_allocate(vp(1:mesh%np, 1:space%dim))
888 vp(1:mesh%np, 1:space%dim) =
m_zero
892 do idir = 1, space%dim
893 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + vp(ip, idir)/
p_c
897 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
898 safe_deallocate_a(vp)
904 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/
p_c
909 assert(
allocated(this%hm_base%uniform_vector_potential))
911 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - am/
p_c
917 if (
associated(gfield))
then
920 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/
p_c
924 if (
allocated(this%ep%e_field) .and.
associated(gfield))
then
925 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
926 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
930 if (
associated(this%xc_photons))
then
931 if(this%xc_photons%lpfmf .and.
allocated(this%xc_photons%mf_vector_potential))
then
934 this%hm_base%uniform_vector_potential(1:space%dim) = &
935 this%hm_base%uniform_vector_potential(1:space%dim) - this%xc_photons%mf_vector_potential(1:space%dim)/
p_c
942 if (
allocated(this%ep%a_static))
then
947 do idir = 1, space%dim
948 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
957 call this%hm_base%accel_copy_pot(mesh)
960 if (
allocated(this%ep%b_field))
then
963 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
968 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
973 if (this%mxll%test_equad)
then
985 integer :: ik, imat, nmat, max_npoints, offset
987 integer :: iphase, nphase
991 if ((.not. this%kpoints%gamma_only()) .or.
allocated(this%hm_base%uniform_vector_potential))
then
995 do iatom = 1, this%ep%natoms
996 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
997 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1003 if (
allocated(this%hm_base%uniform_vector_potential))
then
1005 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1010 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1014 max_npoints = this%vnl%max_npoints
1015 nmat = this%vnl%nprojector_matrices
1018 if (this%phase%is_allocated() .and.
allocated(this%vnl%projector_matrices))
then
1021 if (this%der%boundaries%spiralBC) nphase = 3
1023 if (.not.
allocated(this%vnl%projector_phases))
then
1024 safe_allocate(this%vnl%projector_phases(1:max_npoints, 1:nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1027 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1030 this%vnl%nphase = nphase
1035 do ik = this%d%kpt%start, this%d%kpt%end
1036 do imat = 1, this%vnl%nprojector_matrices
1037 iatom = this%vnl%projector_to_atom(imat)
1038 do iphase = 1, nphase
1040 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1041 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1044 if (
accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0)
then
1046 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1047 offset = offset, async=.
true.)
1049 offset = offset + this%vnl%projector_matrices(imat)%npoints
1070 class(
mesh_t),
intent(in) :: mesh
1071 logical,
optional,
intent(in) :: accumulate
1073 integer :: ispin, ip
1080 do ispin = 1, this%d%nspin
1083 this%hm_base%potential(ip, ispin) =
m_zero
1088 this%hm_base%Impotential =
m_zero
1093 do ispin = 1, this%d%nspin
1094 if (ispin <= 2)
then
1098 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%ep%vpsl(ip) + this%v_ext_pot(ip)
1102 if (this%pcm%run_pcm)
then
1103 if (this%pcm%solute)
then
1106 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1107 this%pcm%v_e_rs(ip) + this%pcm%v_n_rs(ip)
1111 if (this%pcm%localf)
then
1114 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1115 this%pcm%v_ext_rs(ip)
1125 this%hm_base%Impotential(ip, ispin) = this%hm_base%Impotential(ip, ispin) + this%abs_boundaries%mf(ip)
1136 call this%zora%update(this%der, this%hm_base%potential)
1140 do ispin = 1, this%d%nspin
1142 if (
allocated(this%hm_base%zeeman_pot))
then
1145 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%hm_base%zeeman_pot(ip, ispin)
1151 if (this%mxll%test_equad)
then
1154 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%mxll%e_quadrupole_pot(ip)
1163 call this%ks_pot%add_vhxc(this%hm_base%potential)
1165 call this%hm_base%accel_copy_pot(mesh)
1175 type(
grid_t),
intent(in) :: gr
1176 type(
ions_t),
target,
intent(inout) :: ions
1179 real(real64),
optional,
intent(in) :: time
1184 call epot_generate(this%ep, namespace, gr, this%ions, this%d)
1189 if (
allocated(this%ep%e_field) .and. space%periodic_dim < space%dim)
then
1195 this%v_ie_loc%atoms_dist => ions%atoms_dist
1196 this%v_ie_loc%atom => ions%atom
1197 call this%v_ie_loc%calculate()
1200 call lalg_axpy(gr%np,
m_one, this%v_ie_loc%potential(:,1), this%ep%vpsl)
1204 if (this%ep%nlcc)
then
1205 call this%nlcc%end()
1206 call this%nlcc%init(gr, ions)
1207 call this%nlcc%calculate()
1208 call lalg_copy(gr%np, this%nlcc%density(:,1), st%rho_core)
1211 call this%vnl%build(space, gr, this%ep)
1216 if (this%ep%non_local .and. .not. this%vnl%apply_projector_matrices)
then
1218 call messages_write(
'Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.')
1221 call messages_write(
'Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.',&
1223 call messages_write(
'Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
1230 if (this%pcm%run_pcm)
then
1233 if (this%pcm%solute)
then
1240 if (this%pcm%localf .and.
allocated(this%v_static))
then
1241 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, v_ext = this%ep%v_ext(1:gr%np_part))
1246 call lda_u_update_basis(this%lda_u, space, gr, ions, st, this%psolver, namespace, this%kpoints, &
1247 this%phase%is_allocated())
1257 time = this%current_time
1265 apply = this%is_applied_packed
1273 type(namespace_t),
intent(in) :: namespace
1274 class(space_t),
intent(in) :: space
1275 type(lattice_vectors_t),
intent(in) :: latt
1276 class(species_t),
intent(in) :: species
1277 real(real64),
intent(in) :: pos(1:space%dim)
1278 integer,
intent(in) :: ia
1279 class(mesh_t),
intent(in) :: mesh
1280 complex(real64),
intent(in) :: psi(:,:)
1281 complex(real64),
intent(out) :: vpsi(:,:)
1284 real(real64),
allocatable :: vlocal(:)
1287 safe_allocate(vlocal(1:mesh%np_part))
1289 call epot_local_potential(hm%ep, namespace, space, latt, mesh, species, pos, ia, vlocal)
1291 do idim = 1, hm%d%dim
1292 vpsi(1:mesh%np, idim) = vlocal(1:mesh%np) * psi(1:mesh%np, idim)
1295 safe_deallocate_a(vlocal)
1306 class(space_t),
intent(in) :: space
1307 class(mesh_t),
intent(in) :: mesh
1308 type(partner_list_t),
intent(in) :: ext_partners
1309 real(real64),
intent(in) :: time(1:2)
1310 real(real64),
intent(in) :: mu(1:2)
1312 integer :: ispin, ip, idir, iatom, ilaser, itime
1313 real(real64) :: aa(space%dim), bb(space%dim), time_
1314 real(real64),
allocatable :: vp(:,:)
1315 real(real64),
allocatable :: velectric(:)
1316 type(lasers_t),
pointer :: lasers
1317 type(gauge_field_t),
pointer :: gfield
1320 call profiling_in(
"HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1322 this%current_time = m_zero
1323 this%current_time = time(1)
1326 call this%hm_base%clear(mesh%np)
1329 call this%hm_base%allocate_field(mesh, field_potential, &
1330 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1335 lasers => list_get_lasers(ext_partners)
1336 if(
associated(lasers))
then
1337 do ilaser = 1, lasers%no_lasers
1338 select case (laser_kind(lasers%lasers(ilaser)))
1339 case (e_field_scalar_potential, e_field_electric)
1340 safe_allocate(velectric(1:mesh%np))
1341 do ispin = 1, this%d%spin_channels
1343 call laser_potential(lasers%lasers(ilaser), mesh, velectric, time_)
1346 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + mu(itime) * velectric(ip)
1349 safe_deallocate_a(velectric)
1350 case (e_field_magnetic)
1351 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, .false.)
1353 safe_allocate(vp(1:mesh%np, 1:space%dim))
1354 vp(1:mesh%np, 1:space%dim) = m_zero
1355 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1356 do idir = 1, space%dim
1359 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) &
1360 - mu(itime) * vp(ip, idir)/p_c
1365 call laser_field(lasers%lasers(ilaser), bb(1:space%dim), time_)
1366 this%hm_base%uniform_magnetic_field = this%hm_base%uniform_magnetic_field &
1368 safe_deallocate_a(vp)
1369 case (e_field_vector_potential)
1370 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1373 call laser_field(lasers%lasers(ilaser), aa, time_)
1374 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) &
1375 - mu(itime) * aa/p_c
1381 gfield => list_get_gauge_field(ext_partners)
1382 if (
associated(gfield))
then
1383 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1384 call gauge_field_get_vec_pot(gfield, aa)
1385 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1392 if (
allocated(this%ep%e_field) .and.
associated(gfield))
then
1393 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1394 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1400 if (
allocated(this%ep%a_static))
then
1401 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1405 do idir = 1, space%dim
1406 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1412 call this%hm_base%accel_copy_pot(mesh)
1415 if (
allocated(this%ep%b_field))
then
1416 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1418 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1422 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1428 call profiling_out(
"HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1434 integer :: ik, imat, nmat, max_npoints, offset, iphase, nphase
1438 if ((.not. this%kpoints%gamma_only()) .or.
allocated(this%hm_base%uniform_vector_potential))
then
1440 call profiling_in(
'UPDATE_PHASES')
1442 do iatom = 1, this%ep%natoms
1443 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1444 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1447 call profiling_out(
'UPDATE_PHASES')
1450 if (
allocated(this%hm_base%uniform_vector_potential))
then
1451 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1454 max_npoints = this%vnl%max_npoints
1455 nmat = this%vnl%nprojector_matrices
1458 if (this%phase%is_allocated() .and.
allocated(this%vnl%projector_matrices))
then
1461 if (this%der%boundaries%spiralBC) nphase = 3
1463 if (.not.
allocated(this%vnl%projector_phases))
then
1464 safe_allocate(this%vnl%projector_phases(1:max_npoints, nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1465 if (accel_is_enabled())
then
1466 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1467 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1472 do ik = this%d%kpt%start, this%d%kpt%end
1473 do imat = 1, this%vnl%nprojector_matrices
1474 iatom = this%vnl%projector_to_atom(imat)
1475 do iphase = 1, nphase
1477 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1478 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1481 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0)
then
1482 call accel_write_buffer(this%vnl%buff_projector_phases, &
1483 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1486 offset = offset + this%vnl%projector_matrices(imat)%npoints
1500 logical,
intent(in) :: states_are_real
1504 if (hm%self_induced_magnetic)
then
1505 if (.not. states_are_real)
then
1508 message(1) =
'No current density for real states since it is identically zero.'
1509 call messages_warning(1)
1518 type(namespace_t),
intent(in) :: namespace
1519 class(mesh_t),
intent(in) :: mesh
1520 type(states_elec_t),
intent(inout) :: st
1521 type(states_elec_t),
intent(inout) :: hst
1523 integer :: ik, ib, ist
1524 complex(real64),
allocatable :: psi(:, :)
1525 complex(real64),
allocatable :: psiall(:, :, :, :)
1529 do ik = st%d%kpt%start, st%d%kpt%end
1530 do ib = st%group%block_start, st%group%block_end
1535 if (oct_exchange_enabled(hm%oct_exchange))
then
1537 safe_allocate(psiall(mesh%np_part, 1:hst%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1539 call states_elec_get_state(st, mesh, psiall)
1541 call oct_exchange_prepare(hm%oct_exchange, mesh, psiall, hm%xc, hm%psolver, namespace)
1543 safe_deallocate_a(psiall)
1545 safe_allocate(psi(mesh%np_part, 1:hst%d%dim))
1549 call states_elec_get_state(hst, mesh, ist, ik, psi)
1550 call oct_exchange_operator(hm%oct_exchange, namespace, mesh, psi, ist, ik)
1551 call states_elec_set_state(hst, mesh, ist, ik, psi)
1555 safe_deallocate_a(psi)
1565 subroutine magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
1567 type(namespace_t),
intent(in) :: namespace
1568 class(mesh_t),
intent(in) :: mesh
1569 complex(real64),
contiguous,
intent(inout) :: psi(:,:)
1570 complex(real64),
contiguous,
intent(out) :: hpsi(:,:)
1571 integer,
intent(in) :: ik
1572 real(real64),
intent(in) :: vmagnus(:, :, :)
1573 logical,
optional,
intent(in) :: set_phase
1575 complex(real64),
allocatable :: auxpsi(:, :), aux2psi(:, :)
1576 integer :: idim, ispin
1581 if (hm%d%dim /= 1)
then
1582 call messages_not_implemented(
"Magnus with spinors", namespace=namespace)
1585 safe_allocate( auxpsi(1:mesh%np_part, 1:hm%d%dim))
1586 safe_allocate(aux2psi(1:mesh%np, 1:hm%d%dim))
1588 ispin = hm%d%get_spin_index(ik)
1592 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1595 do idim = 1, hm%d%dim
1596 call lalg_copy(mesh%np, auxpsi(:, idim), hpsi(:, idim))
1597 hpsi(1:mesh%np, idim) = hpsi(1:mesh%np, idim) + hm%ep%Vpsl(1:mesh%np)*psi(1:mesh%np,idim)
1598 call vborders(mesh, hm, psi(:, idim), hpsi(:, idim))
1600 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + vmagnus(1:mesh%np, ispin, 2)*psi(1:mesh%np, 1)
1603 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) - m_zi*vmagnus(1:mesh%np, ispin, 1)*auxpsi(1:mesh%np, 1)
1606 auxpsi(1:mesh%np, 1) = vmagnus(1:mesh%np, ispin, 1)*psi(1:mesh%np, 1)
1608 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1609 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + m_zi*aux2psi(1:mesh%np, 1)
1611 safe_deallocate_a(auxpsi)
1612 safe_deallocate_a(aux2psi)
1617 subroutine vborders (mesh, hm, psi, hpsi)
1618 class(mesh_t),
intent(in) :: mesh
1620 complex(real64),
intent(in) :: psi(:)
1621 complex(real64),
intent(inout) :: hpsi(:)
1627 if (hm%abs_boundaries%abtype == imaginary_absorbing)
then
1629 hpsi(ip) = hpsi(ip) + m_zi*hm%abs_boundaries%mf(ip)*psi(ip)
1651 type(namespace_t),
intent(in) :: namespace
1652 real(real64),
intent(in) :: mass
1656 if (parse_is_defined(namespace,
'ParticleMass'))
then
1657 message(1) =
'Attempting to redefine a non-unit electron mass'
1658 call messages_fatal(1)
1675 type(grid_t),
intent(in) :: gr
1676 type(distributed_t),
intent(in) :: kpt
1677 type(wfs_elec_t),
intent(in) :: psib
1678 type(wfs_elec_t),
intent(out) :: psib_with_phase
1680 integer :: k_offset, n_boundary_points
1684 call psib%copy_to(psib_with_phase)
1685 if (hm%phase%is_allocated())
then
1686 call hm%phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.
true.)
1689 k_offset = psib%ik - kpt%start
1690 n_boundary_points = int(gr%np_part - gr%np)
1691 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = hm%phase%phase_corr(:, psib%ik), &
1692 buff_phase_corr = hm%phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.
true.)
1694 call psib%copy_data_to(gr%np, psib_with_phase)
1695 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
1698 call psib_with_phase%do_pack(copy = .
true.)
1706 class(mesh_t),
intent(in) :: mesh
1707 real(real64),
contiguous,
intent(out) :: diag(:,:)
1708 integer,
intent(in) :: ik
1710 integer :: idim, ip, ispin
1712 real(real64),
allocatable :: ldiag(:)
1716 safe_allocate(ldiag(1:mesh%np))
1720 call derivatives_lapl_diag(hm%der, ldiag)
1722 do idim = 1, hm%d%dim
1723 diag(1:mesh%np, idim) = -m_half/hm%mass*ldiag(1:mesh%np)
1726 select case (hm%d%ispin)
1728 case (unpolarized, spin_polarized)
1729 ispin = hm%d%get_spin_index(ik)
1730 diag(1:mesh%np, 1) = diag(1:mesh%np, 1) + hm%ep%vpsl(1:mesh%np)
1734 diag(ip, 1) = diag(ip, 1) + hm%ep%vpsl(ip)
1735 diag(ip, 2) = diag(ip, 2) + hm%ep%vpsl(ip)
1740 call hm%ks_pot%add_vhxc(diag)
1749#include "hamiltonian_elec_inc.F90"
1752#include "complex.F90"
1753#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 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)
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)
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)
pure logical function, public states_are_real(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), parameter, 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.