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
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) )
254 rr = abs(mesh%x(ip, 3))
255 if (rr <= species%thickness() /
m_two)
then
256 in_points = in_points + 1
260 if (mesh%parallel_in_domains)
then
261 call mesh%mpi_grp%allreduce(in_points, in_points_red, 1, mpi_integer, mpi_sum)
262 in_points = in_points_red
265 if (in_points > 0)
then
268 if (mesh%use_curvilinear)
then
270 rr = abs(mesh%x(ip, 3))
271 if (rr <= species%thickness() /
m_two)
then
272 rho(ip, 1:spin_channels) = species%get_zval() / &
273 (mesh%vol_pp(ip)*real(in_points*spin_channels, real64) )
278 rr = abs(mesh%x(ip, 3))
279 if (rr <= species%thickness() /
m_two)
then
280 rho(ip, 1:spin_channels) = species%get_zval() / &
281 (mesh%vol_pp(1)*real(in_points*spin_channels, real64) )
294 assert(
allocated(ps%density))
297 do isp = 1, spin_channels
298 rmax = max(rmax, ps%density(isp)%x_threshold)
302 do icell = 1, latt_iter%n_cells
303 pos_pc = pos + latt_iter%get(icell)
305 call mesh_r(mesh, ip, rr, origin = pos_pc)
308 do isp = 1, spin_channels
310 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
321 do icell = 1, latt_iter%n_cells
322 pos_pc = pos + latt_iter%get(icell)
324 call mesh_r(mesh, ip, rr, origin = pos_pc)
329 do isp = 1, spin_channels
338 do isp = 1, spin_channels
342 rho(1:mesh%np, 1:spin_channels) = rho(1:mesh%np, 1:spin_channels)*species%get_zval()/nrm
352 do isp = 1, spin_channels
353 rho(1:mesh%np, isp) =
m_one
354 x = (species%get_zval()/real(spin_channels, real64) ) /
dmf_integrate(mesh, rho(:, isp))
355 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
365 class(
species_t),
target,
intent(in) :: species
367 real(real64),
intent(in) :: pos(:)
368 type(
mesh_t),
intent(in) :: mesh
369 integer,
intent(in) :: spin_channels
370 real(real64),
intent(inout) :: rho(:, :)
373 real(real64) :: rr, nrm
374 type(
ps_t),
pointer :: ps
388 assert(
allocated(ps%density))
391 do isp = 1, spin_channels
394 call mesh_r(mesh, ip, rr, origin = pos)
397 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
408 call mesh_r(mesh, ip, rr, origin = pos)
413 do isp = 1, spin_channels
421 do isp = 1, spin_channels
425 rho(1:mesh%np, 1:spin_channels) = rho(1:mesh%np, 1:spin_channels)*species%get_zval()/nrm
442 class(
species_t),
target,
intent(in) :: species
446 real(real64),
intent(in) :: pos(1:space%dim)
447 type(
mesh_t),
intent(in) :: mesh
448 integer,
intent(in) :: spin_channels
449 real(real64),
intent(inout) :: drho(:, :)
452 real(real64) :: pos_pc(space%dim), range
453 type(
ps_t),
pointer :: ps
458 assert(spin_channels == 1 .or. spin_channels == 2)
470 range = ps%density_der(1)%x_threshold
471 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
474 do icell = 1, latt_iter%n_cells
475 pos_pc = pos + latt_iter%get(icell)
481 call messages_not_implemented(
'species_atom_density_derivative for non-pseudopotential species', namespace=namespace)
491 class(
species_t),
target,
intent(in) :: species
493 real(real64),
intent(in) :: pos(:)
494 type(
mesh_t),
intent(in) :: mesh
495 integer,
intent(in) :: spin_channels
496 real(real64),
intent(inout) :: drho(:, :)
500 type(
ps_t),
pointer :: ps
512 do isp = 1, spin_channels
515 call mesh_r(mesh, ip, rr, origin = pos)
518 drho(ip, isp) = drho(ip, isp) +
spline_eval(ps%density_der(isp), rr)
543 class(
species_t),
target,
intent(in) :: species
545 class(
space_t),
intent(in) :: space
547 real(real64),
intent(in) :: pos(1:space%dim)
548 type(
mesh_t),
intent(in) :: mesh
549 integer,
intent(in) :: spin_channels
550 real(real64),
intent(inout) :: drho(:, :, :)
552 integer :: isp, ip, icell, idir
553 real(real64) :: rr, pos_pc(space%dim), range, spline
554 type(
ps_t),
pointer :: ps
559 assert(spin_channels == 1 .or. spin_channels == 2)
571 range = ps%density_der(1)%x_threshold
572 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
575 do icell = 1, latt_iter%n_cells
576 pos_pc = pos + latt_iter%get(icell)
579 call mesh_r(mesh, ip, rr, origin = pos_pc)
582 do isp = 1, spin_channels
586 if(abs(spline) < 1e-150_real64) cycle
588 do idir = 1, space%dim
589 drho(ip, isp, idir) = drho(ip, isp, idir) - spline*(mesh%x(ip, idir) - pos_pc(idir))/rr
613 class(
species_t),
target,
intent(in) :: species
615 class(
space_t),
intent(in) :: space
617 real(real64),
target,
intent(in) :: pos(1:space%dim)
618 class(
mesh_t),
target,
intent(in) :: mesh
619 real(real64),
intent(out) :: rho(:)
620 type(
submesh_t),
optional,
target,
intent(inout) :: sphere_inout
621 real(real64),
optional,
intent(inout) :: nlr_x(:,:)
625 real(real64) :: startval(space%dim)
626 real(real64) :: delta, alpha, xx(space%dim), yy(space%dim), rr, imrho1, rerho
627 real(real64) :: dist2_min
628 integer :: icell, ipos, ip, idir, rankmin
630 type(
ps_t),
pointer :: ps
634 logical :: have_point
635 real(real64),
allocatable :: rho_sphere(:)
636 real(real64),
parameter :: threshold = 1e-6_real64
637 real(real64) :: norm_factor, range, radius, radius_nlr, radius_vl
643 if(
present(nlr_x))
then
644 assert(species%is_ps())
647 select type (species)
651 if (
present(sphere_inout))
then
652 radius_vl = ps%vl%x_threshold*1.05_real64
653 radius = max(radius_nlr, radius_vl)
654 call submesh_init(sphere_inout, space, mesh, latt, pos, radius)
655 sphere => sphere_inout
658 call submesh_init(sphere_local, space, mesh, latt, pos, radius)
659 sphere => sphere_local
662 safe_allocate(rho_sphere(1:sphere%np))
663 if (.not.
present(sphere_inout) .and. sphere%np > 0)
then
665 rho_sphere(ip) = sphere%r(ip)
670 if(sphere%r(ip) <= radius_nlr)
then
682 norm_factor = abs(species%get_zval()/
dsm_integrate(mesh, sphere, rho_sphere))
684 rho(sphere%map(ip)) = rho(sphere%map(ip)) + norm_factor*rho_sphere(ip)
687 if (
present(nlr_x))
then
688 do idir = 1, space%dim
690 nlr_x(sphere%map(ip), idir) = nlr_x(sphere%map(ip), idir) + norm_factor*rho_sphere(ip)*sphere%rel_x(idir, ip)
695 safe_deallocate_a(rho_sphere)
697 if ( .not.
present(sphere_inout) )
then
708 if (mesh%mpi_grp%rank /= rankmin) have_point = .false.
711 if (mesh%use_curvilinear)
then
712 rho(ipos) = -species%get_z()/mesh%vol_pp(ipos)
714 rho(ipos) = -species%get_z()/mesh%vol_pp(1)
718 write(
message(1),
'(3a,f5.2,3a)') &
719 "Info: species_full_delta species ", trim(species%get_label()), &
727 if (space%is_periodic())
then
733 if (mesh%use_curvilinear)
then
743 safe_allocate(rho_p(1:mesh%np))
744 safe_allocate(grho_p(1:mesh%np, 1:space%dim))
750 delta = mesh%spacing(1)
751 alpha =
sqrt(
m_two)*species%get_sigma()*delta
755 startval(1:space%dim) = pos
763 write(
message(1),
'(a)')
'Root finding in species_get_density did not converge.'
767 if(
debug%info .and. space%dim == 3)
then
768 write(
message(1),
'(a,3(f6.3,a))')
'Debug: Gaussian charge position (', xx(1),
', ', xx(2),
', ', xx(3),
')'
773 rho = -species%get_z()*rho_p
777 safe_deallocate_a(grho_p)
778 safe_deallocate_a(rho_p)
789 range = latt%max_length()
793 do icell = 1, latt_iter%n_cells
794 yy = latt_iter%get(icell)
796 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
802 rho(ip) = rho(ip) - rerho
810 range = latt%max_length()
814 do icell = 1, latt_iter%n_cells
815 yy = latt_iter%get(icell)
817 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
823 rho(ip) = rho(ip) - rerho
828 rho(1:mesh%np) = rr * rho(1:mesh%np)
840 subroutine func(xin, ff, jacobian)
841 real(real64),
intent(in) :: xin(:)
842 real(real64),
intent(out) :: ff(:), jacobian(:,:)
844 real(real64),
allocatable :: xrho(:)
845 integer :: idir, jdir, dim, ip
852 safe_allocate(xrho(1:mesh_p%np))
858 xrho(ip) = rho_p(ip) * mesh_p%x(ip, idir)
868 xrho(ip) = grho_p(ip, jdir) * mesh_p%x(ip, idir)
874 safe_deallocate_a(xrho)
879 subroutine species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
880 class(
species_t),
target,
intent(in) :: species
881 class(
space_t),
intent(in) :: space
883 real(real64),
intent(in) :: pos(1:space%dim)
884 type(
mesh_t),
intent(in) :: mesh
885 real(real64),
intent(inout) :: rho_core(:)
886 logical,
optional,
intent(in) :: accumulate
888 real(real64) :: center(space%dim), rr
891 type(
ps_t),
pointer :: ps
902 do icell = 1, latt_iter%n_cells
903 center = pos + latt_iter%get(icell)
905 rr = norm2(mesh%x(ip, 1:space%dim) - center)
907 rho_core(ip) = rho_core(ip) +
spline_eval(ps%core, rr)
920 class(
species_t),
target,
intent(in) :: species
921 class(
space_t),
intent(in) :: space
923 real(real64),
intent(in) :: pos(1:space%dim)
924 class(
mesh_t),
intent(in) :: mesh
925 real(real64),
intent(out) :: rho_core_grad(:,:)
926 real(real64),
optional,
intent(inout) :: gnlcc_x(:,:,:)
928 real(real64) :: center(space%dim), rr, spline
929 integer :: icell, ip, idir, jdir
931 type(
ps_t),
pointer :: ps
938 if (.not. species%is_ps())
then
953 do icell = 1, latt_iter%n_cells
954 center = pos + latt_iter%get(icell)
956 call mesh_r(mesh, ip, rr, origin = center)
960 if(abs(spline) < 1e-150_real64) cycle
962 do idir = 1, space%dim
963 rho_core_grad(ip, idir) = rho_core_grad(ip, idir) - spline*(mesh%x(ip, idir)-center(idir))/rr
964 if (
present(gnlcc_x))
then
965 do jdir = 1, space%dim
966 gnlcc_x(ip, idir, jdir) = gnlcc_x(ip, idir, jdir) &
967 - spline*(mesh%x(ip, idir)-center(idir))/rr*(mesh%x(ip, jdir)-center(jdir))
984 subroutine getrho(dim, xin)
985 integer,
intent(in) :: dim
986 real(real64),
intent(in) :: xin(1:dim)
989 real(real64) :: r2, chi(dim), norm, threshold
995 threshold = -
log(0.001_real64)*alpha2_p
999 chi(1:dim) = mesh_p%x(ip,1:dim)
1000 r2 = sum((chi - xin(1:dim))**2)
1002 if (r2 < threshold)
then
1003 rho_p(ip) =
exp(-r2/alpha2_p)
1009 grho_p(ip, idir) = (chi(idir) - xin(idir)) * rho_p(ip)
1024 class(
species_t),
target,
intent(in) :: species
1026 class(
space_t),
intent(in) :: space
1028 real(real64),
intent(in) :: pos(1:space%dim)
1029 type(
mesh_t),
intent(in) :: mesh
1030 real(real64),
intent(out) :: vl(:)
1032 real(real64) :: a1, a2, rb2, range
1033 real(real64) :: xx(space%dim), pos_pc(space%dim), r, r2, threshold
1034 integer :: ip, err, icell
1035 type(
ps_t),
pointer :: ps
1036 complex(real64) :: zpot
1038 real(real64) :: aa, bb
1045 select type(species)
1049 call parse_variable(namespace,
'SpeciesProjectorSphereThreshold', 0.001_real64, threshold)
1055 do icell = 1, latt_iter%n_cells
1056 pos_pc = pos + latt_iter%get(icell)
1058 call mesh_r(mesh, ip, r, origin = pos_pc)
1060 vl(ip) = vl(ip) -species%get_zval()/
sqrt(r2+species%get_softening())
1066 range = 5.0_real64 * latt%max_length()
1069 do icell = 1, latt_iter%n_cells
1070 pos_pc = pos + latt_iter%get(icell)
1072 call mesh_r(mesh, ip, r, origin = pos_pc, coords = xx)
1074 zpot = species%user_pot(space%dim, xx, r)
1075 vl(ip) = vl(ip) + real(zpot, real64)
1081 assert(.not. space%is_periodic())
1083 call dio_function_input(trim(species%get_filename()), namespace, space, mesh, vl, err)
1085 write(
message(1),
'(a)')
'Error loading file '//trim(species%get_filename())//
'.'
1086 write(
message(2),
'(a,i4)')
'Error code returned = ', err
1092 assert(.not. space%is_periodic())
1094 a1 = species%get_z()/(
m_two*species%radius()**3)
1095 a2 = species%get_z()/species%radius()
1096 rb2= species%radius()**2
1100 xx = mesh%x(ip, :) - pos(1:space%dim)
1103 if (r <= species%radius())
then
1104 vl(ip) = (a1*(r*r - rb2) - a2)
1106 vl(ip) = -species%get_z()/r
1112 a1 =
m_two *
m_pi * species%get_z() / (
m_four *mesh%box%bounding_box_l(1) *mesh%box%bounding_box_l(2))
1116 r = abs(mesh%x(ip, 3))
1118 if (r <= species%thickness()/
m_two)
then
1119 vl(ip) = a1 * (r * r / species%thickness() + species%thickness() /
m_four)
1128 assert(.not. space%is_periodic())
1133 r2 = sum((mesh%x(ip, :) - pos)**2)
1145 if (space%is_periodic())
then
1155 r2 = sum((mesh%x(ip, :) - pos)**2)*(species%get_z()*aa)**2
1166 vl(ip) = vl(ip) * (species%get_z())**2
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)
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 messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_experimental(name, 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.
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 ...