28 use,
intrinsic :: iso_fortran_env
55 integer,
public,
parameter :: &
56 SM_POISSON_DIRECT = 0, &
65 class(species_t),
intent(in) :: species
66 integer,
optional,
intent(in) :: iselect
68 integer :: iorb, ii, ll, mm
74 do iorb = 1, species%get_niwfs()
75 call species%get_iwf_ilm(iorb, 1, ii, ll, mm)
76 if (
present(iselect))
then
77 if (ii == iselect) norb = norb + 1
84 subroutine orbitalset_init_intersite(this, namespace, space, ind, ions, der, psolver, os, nos, maxnorbs, &
85 rcut, kpt, has_phase, sm_poisson, basis_from_states)
86 type(orbitalset_t),
intent(inout) :: this
87 type(namespace_t),
intent(in) :: namespace
88 class(space_t),
intent(in) :: space
89 integer,
intent(in) :: ind
90 type(ions_t),
intent(in) :: ions
91 type(derivatives_t),
intent(in) :: der
92 type(poisson_t),
intent(in) :: psolver
93 type(orbitalset_t),
intent(inout) :: os(:)
94 integer,
intent(in) :: nos, maxnorbs
95 real(real64),
intent(in) :: rcut
96 type(distributed_t),
intent(in) :: kpt
97 logical,
intent(in) :: has_phase
98 integer,
intent(in) :: sm_poisson
99 logical,
intent(in) :: basis_from_states
102 type(lattice_iterator_t) :: latt_iter
103 real(real64) :: xat(space%dim), xi(space%dim)
105 integer :: inn, ist, jst
106 integer :: ip, ios, ip2
107 type(submesh_t) :: sm
108 real(real64),
allocatable :: tmp(:), vv(:), nn(:)
109 real(real64),
allocatable :: orb(:,:,:)
110 real(real64),
parameter :: TOL_INTERSITE = 1.e-5_real64
111 type(distributed_t) :: dist
112 integer :: sm_poisson_
118 sm_poisson_ = sm_poisson
121 if (this%iatom /= -1)
then
122 xat = ions%pos(:, this%iatom)
124 xat = this%sphere%center
131 do inn = 1, latt_iter%n_cells
133 xi = os(ios)%sphere%center(1:space%dim) + latt_iter%get(inn)
137 if( rr >rcut + tol_intersite ) cycle
139 if( ios == ind .and. rr < tol_intersite) cycle
141 this%nneighbors = this%nneighbors +1
147 safe_allocate(this%V_ij(1:this%nneighbors, 0:space%dim+1))
148 this%V_ij(1:this%nneighbors, 0:space%dim+1) =
m_zero
149 safe_allocate(this%map_os(1:this%nneighbors))
150 this%map_os(1:this%nneighbors) = 0
152 safe_allocate(this%phase_shift(1:this%nneighbors, kpt%start:kpt%end))
157 do inn = 1, latt_iter%n_cells
158 xi = os(ios)%sphere%center(1:space%dim) + latt_iter%get(inn)
161 if( rr > rcut + tol_intersite ) cycle
162 if( ios == ind .and. rr < tol_intersite) cycle
164 this%nneighbors = this%nneighbors +1
166 this%V_ij(this%nneighbors, 1:space%dim) = xi(1:space%dim) -os(ios)%sphere%center(1:space%dim)
167 this%V_ij(this%nneighbors, space%dim+1) = rr
169 this%map_os(this%nneighbors) = ios
173 write(
message(1),
'(a, i3, a)')
'Intersite interaction will be computed for ', this%nneighbors,
' neighboring atoms.'
177 safe_allocate(this%coulomb_IIJJ(1:this%norbs,1:this%norbs,1:maxnorbs,1:maxnorbs,1:this%nneighbors))
178 this%coulomb_IIJJ =
m_zero
180 if(this%nneighbors == 0)
then
188 if(.not. der%mesh%parallel_in_domains)
then
193 do inn = dist%start, dist%end
195 ios = this%map_os(inn)
197 if(.not. basis_from_states)
then
199 call submesh_merge(sm, space, der%mesh, this%sphere, os(ios)%sphere, &
200 shift = this%V_ij(inn, 1:space%dim))
202 write(
message(1),
'(a, i3, a, f6.3, a, i7, a)')
'Neighbor ', inn,
' is located at ', &
203 this%V_ij(inn, space%dim+1),
' Bohr and has ', sm%np,
' grid points.'
206 safe_allocate(orb(1:sm%np, 1:max(this%norbs,os(ios)%norbs),1:2))
208 do ist = 1, this%norbs
210 1, orb(1:sm%np, ist,1))
213 call submesh_shift_center(sm, space, this%V_ij(inn, 1:space%dim)+os(ios)%sphere%center(1:space%dim))
215 do ist = 1, os(ios)%norbs
217 1, orb(1:sm%np, ist, 2))
222 call submesh_merge(sm, ions%space, der%mesh, this%sphere, os(ios)%sphere, &
223 shift = this%V_ij(inn, 1:ions%space%dim))
225 write(
message(1),
'(a, i3, a, f6.3, a, i5, a)')
'Neighbor ', inn,
' is located at ', &
226 this%V_ij(inn, ions%space%dim+1),
' Bohr and has ', sm%np,
' grid points.'
229 safe_allocate(orb(1:sm%np, 1:max(this%norbs,os(ios)%norbs),1:2))
233 do ist = 1, this%norbs
234 if(
allocated(this%dorb))
then
235 orb(1:this%sphere%np, ist, 1) = this%dorb(:,1,ist)
237 orb(1:this%sphere%np, ist, 1) = real(this%zorb(:,1,ist), real64)
241 call submesh_shift_center(sm, ions%space, this%V_ij(inn, 1:ions%space%dim)+os(ios)%sphere%center(1:ions%space%dim))
245 do ist = 1, os(ios)%norbs
246 if(
allocated(this%dorb))
then
249 do ip = 1, os(ios)%sphere%np
250 if(all(abs(sm%rel_x(1:ions%space%dim, ip2)-os(ios)%sphere%rel_x(1:ions%space%dim, ip)) < 1e-6_real64))
then
251 orb(ip2, ist, 2) = os(ios)%dorb(ip, 1, ist)
258 do ip = 1, os(ios)%sphere%np
259 if(all(abs(sm%rel_x(1:ions%space%dim, ip2)-os(ios)%sphere%rel_x(1:ions%space%dim, ip)) < 1e-6_real64))
then
260 orb(ip2, ist, 2) = real(os(ios)%zorb(ip, 1, ist), real64)
269 safe_allocate(tmp(1:sm%np))
270 safe_allocate(nn(1:sm%np))
271 safe_allocate(vv(1:sm%np))
273 select case (sm_poisson_)
274 case(sm_poisson_direct)
286 do ist = 1, this%norbs
289 nn(ip) = orb(ip, ist, 1)*orb(ip, ist, 1)
296 do jst = 1, os(ios)%norbs
300 tmp(ip) = vv(ip)*orb(ip, jst, 2)*orb(ip, jst, 2)
304 this%coulomb_IIJJ(ist, ist, jst, jst, inn) =
dsm_integrate(der%mesh, sm, tmp, reduce = .false.)
310 safe_deallocate_a(nn)
311 safe_deallocate_a(vv)
312 safe_deallocate_a(tmp)
317 safe_deallocate_a(orb)
320 if(der%mesh%parallel_in_domains)
then
321 call der%mesh%allreduce(this%coulomb_IIJJ)
324 if(dist%parallel)
then
337#include "orbitalset_utils_inc.F90"
340#include "complex.F90"
341#include "orbitalset_utils_inc.F90"
subroutine, public datomic_orbital_get_submesh_safe(species, submesh, ii, ll, mm, ispin, phi)
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public distributed_end(this)
subroutine, public distributed_nullify(this, total)
subroutine, public distributed_init(this, total, comm, tag, scalapack_compat)
Distribute N instances across M processes of communicator comm
real(real64), parameter, public m_zero
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=512), private msg
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public zorbitalset_utils_getorbitals(namespace, os, ions, mesh, use_mesh, normalize)
integer, parameter, public sm_poisson_psolver
integer, parameter, public sm_poisson_isf
subroutine, public dorbitalset_utils_getorbitals(namespace, os, ions, mesh, use_mesh, normalize)
subroutine, public zorbitalset_get_center_of_mass(os, space, mesh, latt)
subroutine, public orbitalset_init_intersite(this, namespace, space, ind, ions, der, psolver, os, nos, maxnorbs, rcut, kpt, has_phase, sm_poisson, basis_from_states)
subroutine, public dorbitalset_get_center_of_mass(os, space, mesh, latt)
integer, parameter, public sm_poisson_fft
integer function, public orbitalset_utils_count(species, iselect)
integer, parameter, public poisson_psolver
integer, parameter, public poisson_fft
subroutine, public dpoisson_solve_sm(this, namespace, sm, pot, rho, all_nodes)
Calculates the Poisson equation. Given the density returns the corresponding potential.
integer, parameter, public poisson_direct_sum
subroutine, public poisson_init_sm(this, namespace, space, main, der, sm, method, force_cmplx)
integer, parameter, public poisson_isf
subroutine, public poisson_end(this)
subroutine, public submesh_end_global(this)
subroutine, public submesh_shift_center(this, space, newcenter)
real(real64) function, public dsm_integrate(mesh, sm, ff, reduce)
subroutine, public submesh_merge(this, space, mesh, sm1, sm2, shift)
subroutine, public submesh_end_cube_map(sm)
subroutine, public submesh_end(this)
subroutine, public submesh_build_global(this, space)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
The following class implements a lattice iterator. It allows one to loop over all cells that are with...