28 use,
intrinsic :: iso_fortran_env
57 integer,
public,
parameter :: &
58 SM_POISSON_DIRECT = 0, &
67 class(species_t),
intent(in) :: species
68 integer,
optional,
intent(in) :: iselect
70 integer :: iorb, ii, ll, mm
76 do iorb = 1, species%get_niwfs()
77 call species%get_iwf_ilm(iorb, 1, ii, ll, mm)
78 if (
present(iselect))
then
79 if (ii == iselect) norb = norb + 1
86 subroutine orbitalset_init_intersite(this, namespace, space, ind, ions, der, psolver, os, nos, maxnorbs, &
87 rcut, kpt, has_phase, sm_poisson, basis_from_states, combine_j_orbitals)
88 type(orbitalset_t),
intent(inout) :: this
89 type(namespace_t),
intent(in) :: namespace
90 class(space_t),
intent(in) :: space
91 integer,
intent(in) :: ind
92 type(ions_t),
intent(in) :: ions
93 type(derivatives_t),
intent(in) :: der
94 type(poisson_t),
intent(in) :: psolver
95 type(orbitalset_t),
intent(inout) :: os(:)
96 integer,
intent(in) :: nos, maxnorbs
97 real(real64),
intent(in) :: rcut
98 type(distributed_t),
intent(in) :: kpt
99 logical,
intent(in) :: has_phase
100 integer,
intent(in) :: sm_poisson
101 logical,
intent(in) :: basis_from_states
102 logical,
intent(in) :: combine_j_orbitals
105 type(lattice_iterator_t) :: latt_iter
106 real(real64) :: xat(space%dim), xi(space%dim)
108 integer :: inn, ist, jst
109 integer :: ip, ios, ip2, is1, is2
110 type(submesh_t) :: sm
111 real(real64),
allocatable :: tmp(:), vv(:), nn(:)
112 complex(real64),
allocatable :: ztmp(:), zvv(:,:), znn(:)
113 real(real64),
allocatable :: dorb(:,:,:,:)
114 complex(real64),
allocatable :: zorb(:,:,:,:)
115 real(real64),
parameter :: TOL_INTERSITE = 1.e-5_real64
116 type(distributed_t) :: dist
117 integer :: sm_poisson_
123 sm_poisson_ = sm_poisson
126 if (this%iatom /= -1)
then
127 xat = ions%pos(:, this%iatom)
129 xat = this%sphere%center
136 do inn = 1, latt_iter%n_cells
138 xi = os(ios)%sphere%center(1:space%dim) + latt_iter%get(inn)
142 if( rr >rcut + tol_intersite ) cycle
144 if( ios == ind .and. rr < tol_intersite) cycle
146 this%nneighbors = this%nneighbors +1
152 safe_allocate(this%V_ij(1:this%nneighbors, 0:space%dim+1))
153 this%V_ij(1:this%nneighbors, 0:space%dim+1) =
m_zero
154 safe_allocate(this%map_os(1:this%nneighbors))
155 this%map_os(1:this%nneighbors) = 0
157 safe_allocate(this%phase_shift(1:this%nneighbors, kpt%start:kpt%end))
162 do inn = 1, latt_iter%n_cells
163 xi = os(ios)%sphere%center(1:space%dim) + latt_iter%get(inn)
166 if( rr > rcut + tol_intersite ) cycle
167 if( ios == ind .and. rr < tol_intersite) cycle
169 this%nneighbors = this%nneighbors +1
171 this%V_ij(this%nneighbors, 1:space%dim) = xi(1:space%dim) -os(ios)%sphere%center(1:space%dim)
172 this%V_ij(this%nneighbors, space%dim+1) = rr
174 this%map_os(this%nneighbors) = ios
178 write(
message(1),
'(a, i3, a)')
'Intersite interaction will be computed for ', this%nneighbors,
' neighboring atoms.'
182 if (this%ndim == 1)
then
183 safe_allocate(this%coulomb_IIJJ(1:this%norbs,1:this%norbs,1:maxnorbs,1:maxnorbs,1:this%nneighbors))
184 this%coulomb_IIJJ =
m_zero
186 safe_allocate(this%zcoulomb_IIJJ(1:this%norbs,1:this%norbs,1:maxnorbs,1:maxnorbs, 1:this%ndim, 1:this%ndim, 1:this%nneighbors))
187 this%zcoulomb_IIJJ =
m_zero
190 if(this%nneighbors == 0)
then
198 if(.not. der%mesh%parallel_in_domains)
then
203 do inn = dist%start, dist%end
205 ios = this%map_os(inn)
207 if(.not. basis_from_states)
then
209 call submesh_merge(sm, space, der%mesh, this%sphere, os(ios)%sphere, &
210 shift = this%V_ij(inn, 1:space%dim))
212 write(
message(1),
'(a, i3, a, f6.3, a, i7, a)')
'Neighbor ', inn,
' is located at ', &
213 this%V_ij(inn, space%dim+1),
' Bohr and has ', sm%np,
' grid points.'
216 if (this%ndim == 1)
then
217 safe_allocate(dorb(1:sm%np, 1:1, 1:max(this%norbs, os(ios)%norbs), 1:2))
219 safe_allocate(zorb(1:sm%np, 1:2, 1:max(this%norbs, os(ios)%norbs), 1:2))
223 if (this%ndim == 1)
then
224 do ist = 1, this%norbs
225 call dget_orbital(this%spec, sm, this%ii, this%ll, this%jj, ist, 1, dorb(:, :, ist, 1), combine_j_orbitals)
228 do ist = 1, this%norbs
229 call zget_orbital(this%spec, sm, this%ii, this%ll, this%jj, ist, 2, zorb(:, :, ist, 1), combine_j_orbitals)
233 call submesh_shift_center(sm, space, this%V_ij(inn, 1:space%dim)+os(ios)%sphere%center(1:space%dim))
236 if (this%ndim == 1)
then
237 do ist = 1, os(ios)%norbs
238 call dget_orbital(os(ios)%spec, sm, os(ios)%ii, os(ios)%ll, os(ios)%jj, ist, 1, dorb(:, :, ist, 2), combine_j_orbitals)
241 do ist = 1, os(ios)%norbs
242 call zget_orbital(os(ios)%spec, sm, os(ios)%ii, os(ios)%ll, os(ios)%jj, ist, 2, zorb(:, :, ist, 2), combine_j_orbitals)
248 assert(this%ndim == 1)
250 call submesh_merge(sm, ions%space, der%mesh, this%sphere, os(ios)%sphere, &
251 shift = this%V_ij(inn, 1:ions%space%dim))
253 write(
message(1),
'(a, i3, a, f6.3, a, i5, a)')
'Neighbor ', inn,
' is located at ', &
254 this%V_ij(inn, ions%space%dim+1),
' Bohr and has ', sm%np,
' grid points.'
257 safe_allocate(dorb(1:sm%np, 1:1, 1:max(this%norbs,os(ios)%norbs), 1:2))
261 do ist = 1, this%norbs
262 if(
allocated(this%dorb))
then
263 dorb(1:this%sphere%np, 1, ist, 1) = this%dorb(:,1,ist)
265 dorb(1:this%sphere%np, 1, ist, 1) = real(this%zorb(:,1,ist), real64)
269 call submesh_shift_center(sm, ions%space, this%V_ij(inn, 1:ions%space%dim)+os(ios)%sphere%center(1:ions%space%dim))
273 do ist = 1, os(ios)%norbs
274 if(
allocated(this%dorb))
then
277 do ip = 1, os(ios)%sphere%np
278 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
279 dorb(ip2, 1, ist, 2) = os(ios)%dorb(ip, 1, ist)
286 do ip = 1, os(ios)%sphere%np
287 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
288 dorb(ip2, 1, ist, 2) = real(os(ios)%zorb(ip, 1, ist), real64)
297 select case (sm_poisson_)
298 case(sm_poisson_direct)
308 force_cmplx=(this%ndim==2))
311 if (this%ndim == 1)
then
312 safe_allocate(tmp(1:sm%np))
313 safe_allocate(nn(1:sm%np))
314 safe_allocate(vv(1:sm%np))
316 do ist = 1, this%norbs
319 nn(ip) = dorb(ip, 1, ist, 1)*dorb(ip, 1, ist, 1)
327 do jst = 1, os(ios)%norbs
331 tmp(ip) = vv(ip)*dorb(ip, 1, jst, 2)*dorb(ip, 1, jst, 2)
335 this%coulomb_IIJJ(ist, ist, jst, jst, inn) =
dsm_integrate(der%mesh, sm, tmp, reduce = .false.)
339 safe_deallocate_a(nn)
340 safe_deallocate_a(vv)
341 safe_deallocate_a(tmp)
344 safe_allocate(ztmp(1:sm%np))
345 safe_allocate(znn(1:sm%np))
346 safe_allocate(zvv(1:sm%np, 1:this%ndim))
348 do ist = 1, this%norbs
349 do is1 = 1, this%ndim
352 znn(ip) = conjg(zorb(ip, is1, ist, 1))*zorb(ip, is1, ist, 1)
361 do jst = 1, os(ios)%norbs
363 do is1 = 1, this%ndim
364 do is2 = 1, this%ndim
367 ztmp(ip) = zvv(ip, is1)*conjg(zorb(ip, is2, jst, 2))*zorb(ip, is2, jst, 2)
371 this%zcoulomb_IIJJ(ist, ist, jst, jst, is1, is2, inn) =
zsm_integrate(der%mesh, sm, ztmp)
377 safe_deallocate_a(znn)
378 safe_deallocate_a(zvv)
379 safe_deallocate_a(ztmp)
388 safe_deallocate_a(dorb)
389 safe_deallocate_a(zorb)
392 if(der%mesh%parallel_in_domains .and. this%ndim == 1)
then
393 call der%mesh%allreduce(this%coulomb_IIJJ)
396 if(dist%parallel)
then
397 if (this%ndim == 1)
then
400 do inn = 1, this%nneighbors
401 do is2 = 1, this%ndim
402 do is1 = 1, this%ndim
403 call comm_allreduce(dist%mpi_grp, this%zcoulomb_IIJJ(:,:,:,:, is1, is2, inn))
419#include "orbitalset_utils_inc.F90"
422#include "complex.F90"
423#include "orbitalset_utils_inc.F90"
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 is intended to contain "only mathematical" functions and procedures.
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
integer, parameter, public sm_poisson_psolver
subroutine zget_orbital(species, sm, i, l, j_in, iorb, ndim, orb, combine_j_orbitals)
Returns an orbital on the intersite submesh.
subroutine, public dorbitalset_utils_getorbitals(namespace, os, ions, mesh, use_mesh, normalize, index_shift)
integer, parameter, public sm_poisson_isf
subroutine, public zorbitalset_get_center_of_mass(os, space, mesh, latt)
subroutine, public zorbitalset_utils_getorbitals(namespace, os, ions, mesh, use_mesh, normalize, index_shift)
subroutine, public orbitalset_init_intersite(this, namespace, space, ind, ions, der, psolver, os, nos, maxnorbs, rcut, kpt, has_phase, sm_poisson, basis_from_states, combine_j_orbitals)
subroutine dget_orbital(species, sm, i, l, j_in, iorb, ndim, orb, combine_j_orbitals)
Returns an orbital on the intersite submesh.
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)
subroutine, public zpoisson_solve_sm(this, namespace, sm, pot, rho, all_nodes)
Calculates the Poisson equation. Given the density returns the corresponding potential.
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)
complex(real64) function, public zsm_integrate(mesh, sm, ff, reduce)
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...