28 use,
intrinsic :: iso_fortran_env
67 type(mesh_t),
pointer :: mesh_p
68 real(real64),
allocatable :: rho_p(:)
69 real(real64),
allocatable :: grho_p(:, :)
70 real(real64) :: alpha2_p
71 real(real64),
pointer :: pos_p(:)
78 class(species_t),
target,
intent(in) :: species
79 type(namespace_t),
intent(in) :: namespace
80 class(space_t),
intent(in) :: space
81 type(lattice_vectors_t),
intent(in) :: latt
82 real(real64),
intent(in) :: pos(1:space%dim)
83 type(mesh_t),
intent(in) :: mesh
84 integer,
intent(in) :: spin_channels
85 real(real64),
intent(inout) :: rho(:, :)
87 integer :: isp, ip, in_points, icell
88 real(real64) :: rr, x, pos_pc(space%dim), nrm, rmax
89 real(real64) :: xx(space%dim), yy(space%dim), rerho, imrho
90 real(real64),
allocatable :: dorbital(:)
91 type(ps_t),
pointer :: ps
92 type(volume_t) :: volume
93 integer :: in_points_red
94 type(lattice_iterator_t) :: latt_iter
95 integer :: iorb, ii, nn, ll, mm
96 real(real64) :: radius, density
97 type(submesh_t) :: sphere
101 assert(spin_channels == 1 .or. spin_channels == 2)
106 select type (species)
118 do isp = 1, spin_channels
119 do iorb = 1, species%get_niwfs()
120 call species%get_iwf_ilm(iorb, isp, ii, ll, mm)
122 call species%get_iwf_n(iorb, isp, nn)
124 radius = species%get_iwf_radius(nn, isp)
126 radius = max(radius,
m_two*maxval(mesh%spacing))
128 call submesh_init(sphere, space, mesh, latt, pos, radius)
129 safe_allocate(dorbital(1:sphere%np))
136 dorbital(ip) = species%conf%occ(ii, isp)/real(2*ll+1, real64) *dorbital(ip)*dorbital(ip)
139 safe_deallocate_a(dorbital)
153 rmax = latt%max_length()
156 do icell = 1, latt_iter%n_cells
157 yy = latt_iter%get(icell)
159 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
165 rho(ip, 1) = rho(ip, 1) + rerho
171 if (spin_channels > 1)
then
172 rho(:, 1) =
m_half*rho(:, 1)
173 rho(:, 2) = rho(:, 1)
177 do isp = 1, spin_channels
179 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
187 rmax = latt%max_length()
190 do icell = 1, latt_iter%n_cells
191 yy = latt_iter%get(icell)
193 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
199 rho(ip, 1) = rho(ip, 1) + rerho
203 if (spin_channels > 1)
then
204 rho(:, 1) =
m_half*rho(:, 1)
205 rho(:, 2) = rho(:, 1)
209 do isp = 1, spin_channels
211 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
218 call mesh_r(mesh, ip, rr, origin = pos)
219 if (rr <= species%radius())
then
220 in_points = in_points + 1
224 if (mesh%parallel_in_domains)
then
225 call mesh%mpi_grp%allreduce(in_points, in_points_red, 1, mpi_integer, mpi_sum)
226 in_points = in_points_red
229 if (in_points > 0)
then
232 if (mesh%use_curvilinear)
then
234 call mesh_r(mesh, ip, rr, origin = pos)
235 if (rr <= species%radius())
then
236 rho(ip, 1:spin_channels) = species%get_zval() / &
237 (mesh%vol_pp(ip) * real(in_points*spin_channels, real64) )
242 call mesh_r(mesh, ip, rr, origin = pos)
243 if (rr <= species%radius())
then
244 rho(ip, 1:spin_channels) = species%get_zval() / &
245 (mesh%vol_pp(1) * real(in_points * spin_channels, real64) )
252 density = species%get_density(mesh%box%bounding_box_l) / spin_channels
255 rr = abs(mesh%x(ip, 3) - pos(3))
256 if (rr <= species%thickness() /
m_two)
then
257 rho(ip, 1:spin_channels) = density
268 assert(
allocated(ps%density))
271 do isp = 1, spin_channels
272 rmax = max(rmax, ps%density(isp)%x_threshold)
276 do icell = 1, latt_iter%n_cells
277 pos_pc = pos + latt_iter%get(icell)
279 call mesh_r(mesh, ip, rr, origin = pos_pc)
282 do isp = 1, spin_channels
284 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
295 do icell = 1, latt_iter%n_cells
296 pos_pc = pos + latt_iter%get(icell)
298 call mesh_r(mesh, ip, rr, origin = pos_pc)
303 do isp = 1, spin_channels
312 do isp = 1, spin_channels
316 rho(1:mesh%np, 1:spin_channels) = rho(1:mesh%np, 1:spin_channels)*species%get_zval()/nrm
326 do isp = 1, spin_channels
327 rho(1:mesh%np, isp) =
m_one
328 x = (species%get_zval()/real(spin_channels, real64) ) /
dmf_integrate(mesh, rho(:, isp))
329 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
339 class(
species_t),
target,
intent(in) :: species
341 real(real64),
intent(in) :: pos(:)
342 type(
mesh_t),
intent(in) :: mesh
343 integer,
intent(in) :: spin_channels
344 real(real64),
intent(inout) :: rho(:, :)
347 real(real64) :: rr, nrm
348 type(
ps_t),
pointer :: ps
362 assert(
allocated(ps%density))
365 do isp = 1, spin_channels
368 call mesh_r(mesh, ip, rr, origin = pos)
371 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
382 call mesh_r(mesh, ip, rr, origin = pos)
387 do isp = 1, spin_channels
395 do isp = 1, spin_channels
399 rho(1:mesh%np, 1:spin_channels) = rho(1:mesh%np, 1:spin_channels)*species%get_zval()/nrm
416 class(
species_t),
target,
intent(in) :: species
420 real(real64),
intent(in) :: pos(1:space%dim)
421 type(
mesh_t),
intent(in) :: mesh
422 integer,
intent(in) :: spin_channels
423 real(real64),
intent(inout) :: drho(:, :)
426 real(real64) :: pos_pc(space%dim), range
427 type(
ps_t),
pointer :: ps
432 assert(spin_channels == 1 .or. spin_channels == 2)
444 range = ps%density_der(1)%x_threshold
445 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
448 do icell = 1, latt_iter%n_cells
449 pos_pc = pos + latt_iter%get(icell)
455 call messages_not_implemented(
'species_atom_density_derivative for non-pseudopotential species', namespace=namespace)
465 class(
species_t),
target,
intent(in) :: species
467 real(real64),
intent(in) :: pos(:)
468 type(
mesh_t),
intent(in) :: mesh
469 integer,
intent(in) :: spin_channels
470 real(real64),
intent(inout) :: drho(:, :)
474 type(
ps_t),
pointer :: ps
486 do isp = 1, spin_channels
489 call mesh_r(mesh, ip, rr, origin = pos)
492 drho(ip, isp) = drho(ip, isp) +
spline_eval(ps%density_der(isp), rr)
517 class(
species_t),
target,
intent(in) :: species
519 class(
space_t),
intent(in) :: space
521 real(real64),
intent(in) :: pos(1:space%dim)
522 type(
mesh_t),
intent(in) :: mesh
523 integer,
intent(in) :: spin_channels
524 real(real64),
intent(inout) :: drho(:, :, :)
526 integer :: isp, ip, icell, idir
527 real(real64) :: rr, pos_pc(space%dim), range, spline
528 type(
ps_t),
pointer :: ps
533 assert(spin_channels == 1 .or. spin_channels == 2)
545 range = ps%density_der(1)%x_threshold
546 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
549 do icell = 1, latt_iter%n_cells
550 pos_pc = pos + latt_iter%get(icell)
553 call mesh_r(mesh, ip, rr, origin = pos_pc)
556 do isp = 1, spin_channels
560 if(abs(spline) < 1e-150_real64) cycle
562 do idir = 1, space%dim
563 drho(ip, isp, idir) = drho(ip, isp, idir) - spline*(mesh%x(ip, idir) - pos_pc(idir))/rr
587 class(
species_t),
target,
intent(in) :: species
589 class(
space_t),
intent(in) :: space
591 real(real64),
target,
intent(in) :: pos(1:space%dim)
592 class(
mesh_t),
target,
intent(in) :: mesh
593 real(real64),
intent(out) :: rho(:)
594 type(
submesh_t),
optional,
target,
intent(inout) :: sphere_inout
595 real(real64),
optional,
intent(inout) :: nlr_x(:,:)
599 real(real64) :: startval(space%dim)
600 real(real64) :: delta, alpha, xx(space%dim), yy(space%dim), rr, imrho1, rerho
601 real(real64) :: dist2_min
602 integer :: icell, ipos, ip, idir, rankmin
604 type(
ps_t),
pointer :: ps
608 logical :: have_point
609 real(real64),
allocatable :: rho_sphere(:)
610 real(real64),
parameter :: threshold = 1e-6_real64
611 real(real64) :: norm_factor, range, radius, radius_nlr, radius_vl
617 if(
present(nlr_x))
then
618 assert(species%is_ps())
621 select type (species)
625 if (
present(sphere_inout))
then
626 radius_vl = ps%vl%x_threshold*1.05_real64
627 radius = max(radius_nlr, radius_vl)
628 call submesh_init(sphere_inout, space, mesh, latt, pos, radius)
629 sphere => sphere_inout
632 call submesh_init(sphere_local, space, mesh, latt, pos, radius)
633 sphere => sphere_local
636 safe_allocate(rho_sphere(1:sphere%np))
637 if (.not.
present(sphere_inout) .and. sphere%np > 0)
then
638 call lalg_copy(sphere%np, sphere%r, rho_sphere)
642 if(sphere%r(ip) <= radius_nlr)
then
654 norm_factor = abs(species%get_zval()/
dsm_integrate(mesh, sphere, rho_sphere))
656 rho(sphere%map(ip)) = rho(sphere%map(ip)) + norm_factor*rho_sphere(ip)
659 if (
present(nlr_x))
then
660 do idir = 1, space%dim
662 nlr_x(sphere%map(ip), idir) = nlr_x(sphere%map(ip), idir) + norm_factor*rho_sphere(ip)*sphere%rel_x(idir, ip)
667 safe_deallocate_a(rho_sphere)
669 if ( .not.
present(sphere_inout) )
then
680 if (mesh%mpi_grp%rank /= rankmin) have_point = .false.
683 if (mesh%use_curvilinear)
then
684 rho(ipos) = -species%get_z()/mesh%vol_pp(ipos)
686 rho(ipos) = -species%get_z()/mesh%vol_pp(1)
690 write(
message(1),
'(3a,f5.2,3a)') &
691 "Info: species_full_delta species ", trim(species%get_label()), &
699 if (space%is_periodic())
then
705 if (mesh%use_curvilinear)
then
715 safe_allocate(rho_p(1:mesh%np))
716 safe_allocate(grho_p(1:mesh%np, 1:space%dim))
722 delta = mesh%spacing(1)
723 alpha =
sqrt(
m_two)*species%get_sigma()*delta
727 startval(1:space%dim) = pos
735 write(
message(1),
'(a)')
'Root finding in species_get_density did not converge.'
739 if(
debug%info .and. space%dim == 3)
then
740 write(
message(1),
'(a,3(f6.3,a))')
'Debug: Gaussian charge position (', xx(1),
', ', xx(2),
', ', xx(3),
')'
745 rho = -species%get_z()*rho_p
749 safe_deallocate_a(grho_p)
750 safe_deallocate_a(rho_p)
761 range = latt%max_length()
765 do icell = 1, latt_iter%n_cells
766 yy = latt_iter%get(icell)
768 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
774 rho(ip) = rho(ip) - rerho
782 range = latt%max_length()
786 do icell = 1, latt_iter%n_cells
787 yy = latt_iter%get(icell)
789 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
795 rho(ip) = rho(ip) - rerho
800 rho(1:mesh%np) = rr * rho(1:mesh%np)
812 subroutine func(xin, ff, jacobian)
813 real(real64),
intent(in) :: xin(:)
814 real(real64),
intent(out) :: ff(:), jacobian(:,:)
816 real(real64),
allocatable :: xrho(:)
817 integer :: idir, jdir, dim, ip
824 safe_allocate(xrho(1:mesh_p%np))
830 xrho(ip) = rho_p(ip) * mesh_p%x(ip, idir)
840 xrho(ip) = grho_p(ip, jdir) * mesh_p%x(ip, idir)
846 safe_deallocate_a(xrho)
851 subroutine species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
852 class(
species_t),
target,
intent(in) :: species
853 class(
space_t),
intent(in) :: space
855 real(real64),
intent(in) :: pos(1:space%dim)
856 type(
mesh_t),
intent(in) :: mesh
857 real(real64),
intent(inout) :: rho_core(:)
858 logical,
optional,
intent(in) :: accumulate
860 real(real64) :: center(space%dim), rr
863 type(
ps_t),
pointer :: ps
874 do icell = 1, latt_iter%n_cells
875 center = pos + latt_iter%get(icell)
877 rr = norm2(mesh%x(ip, 1:space%dim) - center)
879 rho_core(ip) = rho_core(ip) +
spline_eval(ps%core, rr)
892 class(
species_t),
target,
intent(in) :: species
893 class(
space_t),
intent(in) :: space
895 real(real64),
intent(in) :: pos(1:space%dim)
896 class(
mesh_t),
intent(in) :: mesh
897 real(real64),
intent(out) :: rho_core_grad(:,:)
898 real(real64),
optional,
intent(inout) :: gnlcc_x(:,:,:)
900 real(real64) :: center(space%dim), rr, spline
901 integer :: icell, ip, idir, jdir
903 type(
ps_t),
pointer :: ps
910 if (.not. species%is_ps())
then
925 do icell = 1, latt_iter%n_cells
926 center = pos + latt_iter%get(icell)
928 call mesh_r(mesh, ip, rr, origin = center)
932 if(abs(spline) < 1e-150_real64) cycle
934 do idir = 1, space%dim
935 rho_core_grad(ip, idir) = rho_core_grad(ip, idir) - spline*(mesh%x(ip, idir)-center(idir))/rr
936 if (
present(gnlcc_x))
then
937 do jdir = 1, space%dim
938 gnlcc_x(ip, idir, jdir) = gnlcc_x(ip, idir, jdir) &
939 - spline*(mesh%x(ip, idir)-center(idir))/rr*(mesh%x(ip, jdir)-center(jdir))
956 subroutine getrho(dim, xin)
957 integer,
intent(in) :: dim
958 real(real64),
intent(in) :: xin(1:dim)
961 real(real64) :: r2, chi(dim), norm, threshold
967 threshold = -
log(0.001_real64)*alpha2_p
971 chi(1:dim) = mesh_p%x(ip,1:dim)
972 r2 = sum((chi - xin(1:dim))**2)
974 if (r2 < threshold)
then
975 rho_p(ip) =
exp(-r2/alpha2_p)
981 grho_p(ip, idir) = (chi(idir) - xin(idir)) * rho_p(ip)
996 class(
species_t),
target,
intent(in) :: species
998 class(
space_t),
intent(in) :: space
1000 real(real64),
intent(in) :: pos(1:space%dim)
1001 type(
mesh_t),
intent(in) :: mesh
1002 real(real64),
intent(out) :: vl(:)
1004 real(real64) :: a1, a2, rb2, range, density
1005 real(real64) :: xx(space%dim), pos_pc(space%dim), r, r2, threshold
1006 integer :: ip, err, icell
1007 type(
ps_t),
pointer :: ps
1008 complex(real64) :: zpot
1010 real(real64) :: aa, bb
1017 select type(species)
1021 call parse_variable(namespace,
'SpeciesProjectorSphereThreshold', 0.001_real64, threshold)
1027 do icell = 1, latt_iter%n_cells
1028 pos_pc = pos + latt_iter%get(icell)
1030 call mesh_r(mesh, ip, r, origin = pos_pc)
1032 vl(ip) = vl(ip) -species%get_zval()/
sqrt(r2+species%get_softening())
1038 range = 5.0_real64 * latt%max_length()
1041 do icell = 1, latt_iter%n_cells
1042 pos_pc = pos + latt_iter%get(icell)
1044 call mesh_r(mesh, ip, r, origin = pos_pc, coords = xx)
1046 zpot = species%user_pot(space%dim, xx, r)
1047 vl(ip) = vl(ip) + real(zpot, real64)
1053 assert(.not. space%is_periodic())
1055 call dio_function_input(trim(species%get_filename()), namespace, space, mesh, vl, err)
1057 write(
message(1),
'(a)')
'Error loading file '//trim(species%get_filename())//
'.'
1058 write(
message(2),
'(a,i4)')
'Error code returned = ', err
1064 assert(.not. space%is_periodic())
1066 a1 = species%get_z()/(
m_two*species%radius()**3)
1067 a2 = species%get_z()/species%radius()
1068 rb2= species%radius()**2
1072 xx = mesh%x(ip, :) - pos(1:space%dim)
1075 if (r <= species%radius())
then
1076 vl(ip) = (a1*(r*r - rb2) - a2)
1078 vl(ip) = -species%get_z()/r
1087 density = species%get_density(mesh%box%bounding_box_l)
1092 r = abs(mesh%x(ip, 3) - pos(3))
1094 if (r <= species%thickness()/
m_two)
then
1095 vl(ip) = a1 * (r * r / species%thickness() + species%thickness() /
m_four)
1104 assert(.not. space%is_periodic())
1109 r2 = sum((mesh%x(ip, :) - pos)**2)
1121 if (space%is_periodic())
then
1131 r2 = sum((mesh%x(ip, :) - pos)**2)*(species%get_z()*aa)**2
1142 vl(ip) = vl(ip) * (species%get_z())**2
Copies a vector x, to a vector y.
scales a vector by a constant
Both the filling of the function, and the retrieval of the values may be done using single- or double...
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
subroutine, public datomic_orbital_get_submesh(species, submesh, ii, ll, mm, ispin, phi, derivative)
type(debug_t), save, public debug
real(real64), parameter, public m_two
real(real64), parameter, public p_proton_charge
real(real64), parameter, public r_small
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_half
real(real64), parameter, public m_one
real(real64), parameter, public m_three
This module implements the index, used for the mesh points.
subroutine, public dio_function_input(filename, namespace, space, mesh, ff, ierr, map)
Reads a mesh function from file filename, and puts it into ff. If the map argument is passed,...
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
This module defines the meshes, which are used in Octopus.
integer function, public mesh_nearest_point(mesh, pos, dmin, rankmin)
Returns the index of the point which is nearest to a given vector position pos.
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
subroutine, public messages_not_implemented(feature, 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)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
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.
pure logical function, public ps_has_density(ps)
pure logical function, public ps_has_nlcc(ps)
integer, parameter, public root_newton
subroutine, public root_solver_init(rs, namespace, dimensionality, solver_type, maxiter, rel_tolerance, abs_tolerance)
subroutine, public droot_solver_run(rs, func, root, success, startval)
subroutine, public species_get_local(species, namespace, space, latt, pos, mesh, vl)
used when the density is not available, or otherwise the Poisson eqn would be used instead
subroutine func(xin, ff, jacobian)
subroutine, public species_atom_density_np(species, namespace, pos, mesh, spin_channels, rho)
subroutine, public species_get_long_range_density(species, namespace, space, latt, pos, mesh, rho, sphere_inout, nlr_x)
subroutine, public species_atom_density_derivative_np(species, namespace, pos, mesh, spin_channels, drho)
subroutine, public species_get_nlcc_grad(species, space, latt, pos, mesh, rho_core_grad, gnlcc_x)
subroutine, public species_atom_density_grad(species, namespace, space, latt, pos, mesh, spin_channels, drho)
subroutine getrho(dim, xin)
subroutine, public species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
subroutine, public species_atom_density(species, namespace, space, latt, pos, mesh, spin_channels, rho)
subroutine, public species_atom_density_derivative(species, namespace, space, latt, pos, mesh, spin_channels, drho)
real(real64) function, public spline_x_threshold(spl, threshold)
Determines the largest value of x for which the spline values are above the threshold.
real(real64) function, public spline_eval(spl, x)
real(real64) pure function, public spline_range_max(this)
real(real64) function, public dsm_integrate(mesh, sm, ff, reduce)
subroutine, public submesh_end(this)
subroutine, public submesh_init(this, space, mesh, latt, center, rc)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
subroutine, public volume_read_from_block(vol, namespace, block_name)
logical function, public volume_in_volume(space, vol, xx)
subroutine, public volume_end(vol)
subroutine, public volume_init(vol)
subroutine generate_uniform_density()
An abstract type for all electron species.
The following class implements a lattice iterator. It allows one to loop over all cells that are with...
Describes mesh distribution to nodes.
A type storing the information and data about a pseudopotential.
An abstract class for species. Derived classes include jellium, all electron, and pseudopotential spe...
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...