28 use,
intrinsic :: iso_fortran_env
57 integer,
public,
parameter :: &
58 SM_POISSON_DIRECT = 0, &
72 class(species_t),
intent(in) :: species
73 integer,
optional,
intent(in) :: iselect
75 integer :: iorb, ii, ll, mm
78 do iorb = 1, species%get_niwfs()
79 call species%get_iwf_ilm(iorb, 1, ii, ll, mm)
80 if (
present(iselect))
then
81 if (ii == iselect) norb = norb + 1
88 subroutine orbitalset_init_intersite(this, namespace, space, grp, ind, ions, der, psolver, os, nos, maxnorbs, &
89 rcut, kpt, has_phase, sm_poisson, basis_from_states, combine_j_orbitals)
90 type(orbitalset_t),
intent(inout) :: this
91 type(namespace_t),
intent(in) :: namespace
92 class(space_t),
intent(in) :: space
93 type(mpi_grp_t),
intent(in) :: grp
94 integer,
intent(in) :: ind
95 type(ions_t),
intent(in) :: ions
96 type(derivatives_t),
intent(in) :: der
97 type(poisson_t),
intent(in) :: psolver
98 type(orbitalset_t),
intent(inout) :: os(:)
99 integer,
intent(in) :: nos, maxnorbs
100 real(real64),
intent(in) :: rcut
101 type(distributed_t),
intent(in) :: kpt
102 logical,
intent(in) :: has_phase
103 integer,
intent(in) :: sm_poisson
104 logical,
intent(in) :: basis_from_states
105 logical,
intent(in) :: combine_j_orbitals
108 type(lattice_iterator_t) :: latt_iter
109 real(real64) :: xat(space%dim), xi(space%dim)
111 integer :: inn, ist, jst, nneighbors, norbs, ndim
112 integer :: ip, ios, ip2, is1, is2
113 type(submesh_t) :: sm
114 real(real64),
allocatable :: tmp(:), vv(:), nn(:)
115 complex(real64),
allocatable :: ztmp(:), zvv(:,:), znn(:)
116 real(real64),
allocatable :: dorb(:,:,:,:)
117 complex(real64),
allocatable :: zorb(:,:,:,:)
118 real(real64),
parameter :: TOL_INTERSITE = 1.e-5_real64
119 type(distributed_t) :: dist
120 integer :: sm_poisson_
126 sm_poisson_ = sm_poisson
130 if (this%iatom /= -1)
then
131 xat = ions%pos(:, this%iatom)
133 xat = this%sphere%center
140 do inn = 1, latt_iter%n_cells
142 xi = os(ios)%sphere%center(1:space%dim) + latt_iter%get(inn)
146 if( rr >rcut + tol_intersite ) cycle
148 if( ios == ind .and. rr < tol_intersite) cycle
150 this%nneighbors = this%nneighbors +1
156 safe_allocate(this%V_ij(1:this%nneighbors, 0:space%dim+1))
157 this%V_ij(1:this%nneighbors, 0:space%dim+1) =
m_zero
158 safe_allocate(this%map_os(1:this%nneighbors))
159 this%map_os(1:this%nneighbors) = 0
161 safe_allocate(this%phase_shift(1:this%nneighbors, kpt%start:kpt%end))
166 do inn = 1, latt_iter%n_cells
167 xi = os(ios)%sphere%center(1:space%dim) + latt_iter%get(inn)
170 if( rr > rcut + tol_intersite ) cycle
171 if( ios == ind .and. rr < tol_intersite) cycle
173 this%nneighbors = this%nneighbors +1
175 this%V_ij(this%nneighbors, 1:space%dim) = xi(1:space%dim) -os(ios)%sphere%center(1:space%dim)
176 this%V_ij(this%nneighbors, space%dim+1) = rr
178 this%map_os(this%nneighbors) = ios
182 write(
message(1),
'(a, i3, a)')
'Intersite interaction will be computed for ', this%nneighbors,
' neighboring atoms.'
187 nneighbors = this%nneighbors
190 safe_allocate(this%coulomb_IIJJ(1:norbs,1:norbs,1:maxnorbs,1:maxnorbs,1:nneighbors))
191 this%coulomb_IIJJ =
m_zero
193 safe_allocate(this%zcoulomb_IIJJ(1:norbs,1:norbs,1:maxnorbs,1:maxnorbs, 1:ndim, 1:ndim, 1:nneighbors))
194 this%zcoulomb_IIJJ =
m_zero
197 if(this%nneighbors == 0)
then
205 if(.not. der%mesh%parallel_in_domains)
then
210 do inn = dist%start, dist%end
212 ios = this%map_os(inn)
214 if(.not. basis_from_states)
then
216 call submesh_merge(sm, space, der%mesh, this%sphere, os(ios)%sphere, &
217 shift = this%V_ij(inn, 1:space%dim))
219 write(
message(1),
'(a, i3, a, f6.3, a, i7, a)')
'Neighbor ', inn,
' is located at ', &
220 this%V_ij(inn, space%dim+1),
' Bohr and has ', sm%np,
' grid points.'
224 safe_allocate(dorb(1:sm%np, 1:1, 1:max(this%norbs, os(ios)%norbs), 1:2))
226 safe_allocate(zorb(1:sm%np, 1:2, 1:max(this%norbs, os(ios)%norbs), 1:2))
231 do ist = 1, this%norbs
232 call dget_orbital(this%spec, sm, this%ii, this%ll, this%jj, ist, 1, dorb(:, :, ist, 1), combine_j_orbitals)
235 do ist = 1, this%norbs
236 call zget_orbital(this%spec, sm, this%ii, this%ll, this%jj, ist, 2, zorb(:, :, ist, 1), combine_j_orbitals)
240 call submesh_shift_center(sm, space, this%V_ij(inn, 1:space%dim)+os(ios)%sphere%center(1:space%dim))
244 do ist = 1, os(ios)%norbs
245 call dget_orbital(os(ios)%spec, sm, os(ios)%ii, os(ios)%ll, os(ios)%jj, ist, 1, dorb(:, :, ist, 2), combine_j_orbitals)
248 do ist = 1, os(ios)%norbs
249 call zget_orbital(os(ios)%spec, sm, os(ios)%ii, os(ios)%ll, os(ios)%jj, ist, 2, zorb(:, :, ist, 2), combine_j_orbitals)
257 call submesh_merge(sm, space, der%mesh, this%sphere, os(ios)%sphere, &
258 shift = this%V_ij(inn, 1:space%dim))
260 write(
message(1),
'(a, i3, a, f6.3, a, i5, a)')
'Neighbor ', inn,
' is located at ', &
261 this%V_ij(inn, space%dim+1),
' Bohr and has ', sm%np,
' grid points.'
264 safe_allocate(dorb(1:sm%np, 1:1, 1:max(this%norbs,os(ios)%norbs), 1:2))
268 do ist = 1, this%norbs
269 if(
allocated(this%dorb))
then
270 dorb(1:this%sphere%np, 1, ist, 1) = this%dorb(:,1,ist)
272 dorb(1:this%sphere%np, 1, ist, 1) = real(this%zorb(:,1,ist), real64)
276 call submesh_shift_center(sm, space, this%V_ij(inn, 1:space%dim)+os(ios)%sphere%center(1:space%dim))
280 do ist = 1, os(ios)%norbs
281 if(
allocated(this%dorb))
then
284 do ip = 1, os(ios)%sphere%np
285 if(all(abs(sm%rel_x(1:space%dim, ip2)-os(ios)%sphere%rel_x(1:space%dim, ip)) <
r_small))
then
286 dorb(ip2, 1, ist, 2) = os(ios)%dorb(ip, 1, ist)
293 do ip = 1, os(ios)%sphere%np
294 if(all(abs(sm%rel_x(1:space%dim, ip2)-os(ios)%sphere%rel_x(1:space%dim, ip)) <
r_small))
then
295 dorb(ip2, 1, ist, 2) = real(os(ios)%zorb(ip, 1, ist), real64)
304 select case (sm_poisson_)
305 case(sm_poisson_direct)
315 force_cmplx=(ndim==2))
319 safe_allocate(tmp(1:sm%np))
320 safe_allocate(nn(1:sm%np))
321 safe_allocate(vv(1:sm%np))
323 do ist = 1, this%norbs
326 nn(ip) = dorb(ip, 1, ist, 1)*dorb(ip, 1, ist, 1)
334 do jst = 1, os(ios)%norbs
338 tmp(ip) = vv(ip)*dorb(ip, 1, jst, 2)*dorb(ip, 1, jst, 2)
342 this%coulomb_IIJJ(ist, ist, jst, jst, inn) =
dsm_integrate(der%mesh, sm, tmp, reduce = .false.)
346 safe_deallocate_a(nn)
347 safe_deallocate_a(vv)
348 safe_deallocate_a(tmp)
351 safe_allocate(ztmp(1:sm%np))
352 safe_allocate(znn(1:sm%np))
353 safe_allocate(zvv(1:sm%np, 1:ndim))
355 do ist = 1, this%norbs
359 znn(ip) = conjg(zorb(ip, is1, ist, 1))*zorb(ip, is1, ist, 1)
368 do jst = 1, os(ios)%norbs
374 ztmp(ip) = zvv(ip, is1)*conjg(zorb(ip, is2, jst, 2))*zorb(ip, is2, jst, 2)
378 this%zcoulomb_IIJJ(ist, ist, jst, jst, is1, is2, inn) =
zsm_integrate(der%mesh, sm, ztmp)
384 safe_deallocate_a(znn)
385 safe_deallocate_a(zvv)
386 safe_deallocate_a(ztmp)
395 safe_deallocate_a(dorb)
396 safe_deallocate_a(zorb)
399 if(this%ndim == 1)
then
400 call der%mesh%allreduce(this%coulomb_IIJJ)
403 if(dist%parallel)
then
407 do inn = 1, this%nneighbors
410 call comm_allreduce(dist%mpi_grp, this%zcoulomb_IIJJ(:,:,:,:, is1, is2, inn))
426#include "orbitalset_utils_inc.F90"
429#include "complex.F90"
430#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 r_small
real(real64), parameter, public m_zero
System information (time, memory, sysname)
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
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
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 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)
subroutine, public orbitalset_init_intersite(this, namespace, space, grp, ind, ions, der, psolver, os, nos, maxnorbs, rcut, kpt, has_phase, sm_poisson, basis_from_states, combine_j_orbitals)
integer, parameter, public sm_poisson_fft
integer function, public orbitalset_utils_count(species, iselect)
Count the number of orbital sets we have for a given atom.
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 poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
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
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...