29 use,
intrinsic :: iso_fortran_env
68 type(mesh_t),
pointer :: mesh_p
69 real(real64),
allocatable :: rho_p(:)
70 real(real64),
allocatable :: grho_p(:, :)
71 real(real64) :: alpha2_p
72 real(real64),
pointer :: pos_p(:)
79 class(species_t),
target,
intent(in) :: species
80 type(namespace_t),
intent(in) :: namespace
81 class(space_t),
intent(in) :: space
82 type(lattice_vectors_t),
intent(in) :: latt
83 real(real64),
intent(in) :: pos(1:space%dim)
84 type(mesh_t),
intent(in) :: mesh
85 integer,
intent(in) :: spin_channels
86 real(real64),
intent(inout) :: rho(:, :)
88 integer :: isp, ip, in_points, icell
89 real(real64) :: rr, x, pos_pc(space%dim), nrm, rmax
90 real(real64) :: xx(space%dim), yy(space%dim), rerho, imrho
91 real(real64),
allocatable :: dorbital(:)
92 type(ps_t),
pointer :: ps
93 type(volume_t) :: volume
94 integer :: in_points_red
95 type(lattice_iterator_t) :: latt_iter
96 integer :: iorb, ii, nn, ll, mm
97 real(real64) :: radius, density
98 type(submesh_t) :: sphere
102 assert(spin_channels == 1 .or. spin_channels == 2)
107 select type (species)
119 do isp = 1, spin_channels
120 do iorb = 1, species%get_niwfs()
121 call species%get_iwf_ilm(iorb, isp, ii, ll, mm)
123 call species%get_iwf_n(iorb, isp, nn)
125 radius = species%get_iwf_radius(nn, isp)
127 radius = max(radius,
m_two*maxval(mesh%spacing))
129 call submesh_init(sphere, space, mesh, latt, pos, radius)
130 safe_allocate(dorbital(1:sphere%np))
137 dorbital(ip) = species%conf%occ(ii, isp)/real(2*ll+1, real64) *dorbital(ip)*dorbital(ip)
140 safe_deallocate_a(dorbital)
154 rmax = latt%max_length()
157 do icell = 1, latt_iter%n_cells
158 yy = latt_iter%get(icell)
160 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
166 rho(ip, 1) = rho(ip, 1) + rerho
172 if (spin_channels > 1)
then
174 rho(:, 2) = rho(:, 1)
178 do isp = 1, spin_channels
182 rho(ip, isp) = x * rho(ip, isp)
192 rmax = latt%max_length()
195 do icell = 1, latt_iter%n_cells
196 yy = latt_iter%get(icell)
198 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
204 rho(ip, 1) = rho(ip, 1) + rerho
208 if (spin_channels > 1)
then
209 rho(:, 1) =
m_half*rho(:, 1)
210 rho(:, 2) = rho(:, 1)
214 do isp = 1, spin_channels
218 rho(ip, isp) = x * rho(ip, isp)
227 call mesh_r(mesh, ip, rr, origin = pos)
228 if (rr <= species%radius())
then
229 in_points = in_points + 1
233 if (mesh%parallel_in_domains)
then
234 call mesh%mpi_grp%allreduce(in_points, in_points_red, 1, mpi_integer, mpi_sum)
235 in_points = in_points_red
238 if (in_points > 0)
then
241 if (mesh%use_curvilinear)
then
243 call mesh_r(mesh, ip, rr, origin = pos)
244 if (rr <= species%radius())
then
245 rho(ip, 1:spin_channels) = species%get_zval() / &
246 (mesh%vol_pp(ip) * real(in_points*spin_channels, real64) )
251 call mesh_r(mesh, ip, rr, origin = pos)
252 if (rr <= species%radius())
then
253 rho(ip, 1:spin_channels) = species%get_zval() / &
254 (mesh%vol_pp(1) * real(in_points * spin_channels, real64) )
261 density = species%get_density(mesh%box%bounding_box_l) / spin_channels
264 rr = abs(mesh%x(3, ip) - pos(3))
265 if (rr <= species%thickness() /
m_two)
then
266 rho(ip, 1:spin_channels) = density
277 assert(
allocated(ps%density))
280 do isp = 1, spin_channels
281 rmax = max(rmax, ps%density(isp)%x_threshold)
285 do icell = 1, latt_iter%n_cells
286 pos_pc = pos + latt_iter%get(icell)
288 call mesh_r(mesh, ip, rr, origin = pos_pc)
291 do isp = 1, spin_channels
293 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
304 do icell = 1, latt_iter%n_cells
305 pos_pc = pos + latt_iter%get(icell)
307 call mesh_r(mesh, ip, rr, origin = pos_pc)
312 do isp = 1, spin_channels
321 do isp = 1, spin_channels
325 do isp = 1, spin_channels
326 call lalg_scal(mesh%np, species%get_zval()/nrm, rho(:, isp))
337 do isp = 1, spin_channels
338 rho(1:mesh%np, isp) =
m_one
339 x = (species%get_zval()/real(spin_channels, real64) ) /
dmf_integrate(mesh, rho(:, isp))
340 rho(1:mesh%np, isp) = x
350 class(
species_t),
target,
intent(in) :: species
352 real(real64),
intent(in) :: pos(:)
353 type(
mesh_t),
intent(in) :: mesh
354 integer,
intent(in) :: spin_channels
355 real(real64),
intent(inout) :: rho(:, :)
358 real(real64) :: rr, nrm
359 type(
ps_t),
pointer :: ps
373 assert(
allocated(ps%density))
376 do isp = 1, spin_channels
379 call mesh_r(mesh, ip, rr, origin = pos)
382 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
393 call mesh_r(mesh, ip, rr, origin = pos)
398 do isp = 1, spin_channels
406 do isp = 1, spin_channels
410 do isp = 1, spin_channels
411 call lalg_scal(mesh%np, species%get_zval()/nrm, rho(:, isp))
428 class(
species_t),
target,
intent(in) :: species
430 real(real64),
intent(in) :: pos(:)
432 integer,
intent(in) :: spin_channels
433 real(real64),
intent(inout) :: drho(:, :)
437 type(
ps_t),
pointer :: ps
449 do isp = 1, spin_channels
452 call mesh_r(mesh, ip, rr, origin = pos)
455 drho(ip, isp) = drho(ip, isp) +
spline_eval(ps%density_der(isp), rr)
480 class(
species_t),
target,
intent(in) :: species
482 class(
space_t),
intent(in) :: space
484 real(real64),
intent(in) :: pos(1:space%dim)
485 type(
mesh_t),
intent(in) :: mesh
486 integer,
intent(in) :: spin_channels
487 real(real64),
intent(inout) :: drho(:, :, :)
489 integer :: isp, ip, icell, idir
490 real(real64) :: rr, pos_pc(space%dim), range, spline
491 type(
ps_t),
pointer :: ps
496 assert(spin_channels == 1 .or. spin_channels == 2)
508 range = ps%density_der(1)%x_threshold
509 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
512 do icell = 1, latt_iter%n_cells
513 pos_pc = pos + latt_iter%get(icell)
516 call mesh_r(mesh, ip, rr, origin = pos_pc)
519 do isp = 1, spin_channels
523 if(abs(spline) < 1e-150_real64) cycle
525 do idir = 1, space%dim
526 drho(ip, isp, idir) = drho(ip, isp, idir) - spline*(mesh%x(idir, ip) - pos_pc(idir))/rr
550 class(
species_t),
target,
intent(in) :: species
552 class(
space_t),
intent(in) :: space
554 real(real64),
target,
intent(in) :: pos(1:space%dim)
555 class(
mesh_t),
target,
intent(in) :: mesh
556 real(real64),
intent(out) :: rho(:)
557 type(
submesh_t),
optional,
target,
intent(inout) :: sphere_inout
558 real(real64),
optional,
intent(inout) :: nlr_x(:,:)
562 real(real64) :: startval(space%dim)
563 real(real64) :: delta, alpha, xx(space%dim), yy(space%dim), rr, imrho1, rerho
564 real(real64) :: dist2_min
565 integer :: icell, ipos, ip, idir, rankmin
567 type(
ps_t),
pointer :: ps
571 logical :: have_point
572 real(real64),
allocatable :: rho_sphere(:)
573 real(real64),
parameter :: threshold = 1e-6_real64
574 real(real64) :: norm_factor, range, radius, radius_nlr, radius_vl
580 if(
present(nlr_x))
then
581 assert(species%is_ps())
584 select type (species)
588 if (
present(sphere_inout))
then
589 radius_vl = ps%vl%x_threshold*1.05_real64
590 radius = max(radius_nlr, radius_vl)
591 call submesh_init(sphere_inout, space, mesh, latt, pos, radius)
592 sphere => sphere_inout
595 call submesh_init(sphere_local, space, mesh, latt, pos, radius)
596 sphere => sphere_local
599 safe_allocate(rho_sphere(1:sphere%np))
600 if (.not.
present(sphere_inout) .and. sphere%np > 0)
then
601 call lalg_copy(sphere%np, sphere%r, rho_sphere)
605 if(sphere%r(ip) <= radius_nlr)
then
617 norm_factor = abs(species%get_zval()/
dsm_integrate(mesh, sphere, rho_sphere))
619 rho(sphere%map(ip)) = rho(sphere%map(ip)) + norm_factor*rho_sphere(ip)
622 if (
present(nlr_x))
then
623 do idir = 1, space%dim
625 nlr_x(sphere%map(ip), idir) = nlr_x(sphere%map(ip), idir) + norm_factor*rho_sphere(ip)*sphere%rel_x(idir, ip)
630 safe_deallocate_a(rho_sphere)
632 if ( .not.
present(sphere_inout) )
then
643 if (mesh%mpi_grp%rank /= rankmin) have_point = .false.
646 if (mesh%use_curvilinear)
then
647 rho(ipos) = -species%get_z()/mesh%vol_pp(ipos)
649 rho(ipos) = -species%get_z()/mesh%vol_pp(1)
653 write(
message(1),
'(3a,f12.6,3a)') &
654 "Info: species_full_delta species ", trim(species%get_label()), &
662 if (space%is_periodic())
then
669 select type (cs => mesh%coord_system)
681 safe_allocate(rho_p(1:mesh%np))
682 safe_allocate(grho_p(1:mesh%np, 1:space%dim))
688 delta = mesh%spacing(1)
689 alpha =
sqrt(
m_two)*species%get_sigma()*delta
693 startval(1:space%dim) = mesh%coord_system%from_cartesian(pos)
701 write(
message(1),
'(a)')
'Root finding in species_get_density did not converge.'
707 "Info: species_full_gaussian species ", trim(species%get_label()),
":"
708 write(
message(2),
'(a,f12.6,a,f12.6)') &
709 " sigma = ", species%get_sigma(),
" spacing = ", delta
710 write(
message(3),
'(a,f12.6,a,f12.6,a)') &
711 " alpha = ", alpha,
" zeta = ",
m_one/alpha2_p,
" [bohr^-2]"
714 if(
debug%info .and. space%dim == 3)
then
715 write(
message(1),
'(a,3(f6.3,a))') &
716 'Debug: Gaussian charge position in primitive coordinates (', xx(1),
', ', xx(2),
', ', xx(3),
')'
721 rho = -species%get_z()*rho_p
725 safe_deallocate_a(grho_p)
726 safe_deallocate_a(rho_p)
737 range = latt%max_length()
741 do icell = 1, latt_iter%n_cells
742 yy = latt_iter%get(icell)
744 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
750 rho(ip) = rho(ip) - rerho
758 range = latt%max_length()
762 do icell = 1, latt_iter%n_cells
763 yy = latt_iter%get(icell)
765 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
771 rho(ip) = rho(ip) - rerho
788 subroutine func(xin, ff, jacobian)
789 real(real64),
intent(in) :: xin(:)
790 real(real64),
intent(out) :: ff(:), jacobian(:,:)
792 real(real64),
allocatable :: xrho(:)
793 integer :: idir, jdir, dim, ip
800 safe_allocate(xrho(1:mesh_p%np))
806 xrho(ip) = rho_p(ip) * mesh_p%x_t(ip, idir)
816 xrho(ip) = grho_p(ip, jdir) * mesh_p%x_t(ip, idir)
822 safe_deallocate_a(xrho)
827 subroutine species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
828 class(
species_t),
target,
intent(in) :: species
829 class(
space_t),
intent(in) :: space
831 real(real64),
intent(in) :: pos(1:space%dim)
832 class(
mesh_t),
intent(in) :: mesh
833 real(real64),
intent(inout) :: rho_core(:)
834 logical,
optional,
intent(in) :: accumulate
836 real(real64) :: center(space%dim), rr
839 type(
ps_t),
pointer :: ps
849 if (.not. species%has_nlcc())
then
855 do icell = 1, latt_iter%n_cells
856 center = pos + latt_iter%get(icell)
858 rr = norm2(mesh%x(1:space%dim, ip) - center)
860 rho_core(ip) = rho_core(ip) +
spline_eval(ps%core, rr)
885 class(
species_t),
target,
intent(in) :: species
886 class(
space_t),
intent(in) :: space
888 real(real64),
intent(in) :: pos(1:space%dim)
889 class(
mesh_t),
intent(in) :: mesh
890 real(real64),
intent(inout) :: rho_core_grad_x(:,:,:)
892 real(real64) :: center(space%dim), dd(space%dim), rr, drho
893 integer :: icell, ip, idir, jdir
895 type(
ps_t),
pointer :: ps
906 if (.not. species%has_nlcc())
then
912 do icell = 1, latt_iter%n_cells
913 center = pos + latt_iter%get(icell)
915 dd(1:space%dim) = mesh%x(1:space%dim, ip) - center
920 do idir = 1, space%dim
921 do jdir = idir, space%dim
922 rho_core_grad_x(ip, idir, jdir) = rho_core_grad_x(ip, idir, jdir) &
923 + drho * dd(idir) * dd(jdir)
930 do idir = 1, space%dim
931 do jdir = idir + 1, space%dim
932 rho_core_grad_x(1:mesh%np, jdir, idir) = rho_core_grad_x(1:mesh%np, idir, jdir)
951 class(
species_t),
target,
intent(in) :: species
952 class(
space_t),
intent(in) :: space
954 real(real64),
intent(in) :: pos(1:space%dim)
955 class(
mesh_t),
intent(in) :: mesh
956 real(real64),
intent(out) :: grad_rho_core(:,:)
958 real(real64) :: center(space%dim), dd(space%dim), rr, drho
959 integer :: icell, ip, idir
961 type(
ps_t),
pointer :: ps
972 if (.not. species%has_nlcc())
then
978 do icell = 1, latt_iter%n_cells
979 center = pos + latt_iter%get(icell)
981 dd(1:space%dim) = mesh%x(1:space%dim, ip) - center
986 do idir = 1, space%dim
987 grad_rho_core(ip, idir) = grad_rho_core(ip, idir) + drho * dd(idir)
1000 subroutine getrho(dim, xin)
1001 integer,
intent(in) :: dim
1002 real(real64),
intent(in) :: xin(1:dim)
1005 real(real64) :: r2, chi(dim), norm, threshold
1013 threshold = -
log(0.0001_real64)*alpha2_p
1015 do ip = 1, mesh_p%np
1018 chi(1:dim) = mesh_p%chi(1:dim, ip)
1019 r2 = sum((chi - xin(1:dim))**2)
1021 if (r2 < threshold)
then
1022 rho_p(ip) =
exp(-r2/alpha2_p)
1028 grho_p(ip, idir) = (chi(idir) - xin(idir)) * rho_p(ip)
1043 class(
species_t),
target,
intent(in) :: species
1047 real(real64),
intent(in) :: pos(1:space%dim)
1048 type(
mesh_t),
intent(in) :: mesh
1049 real(real64),
intent(out) :: vl(:)
1051 real(real64) :: a1, a2, rb2, range, density
1052 real(real64) :: xx(space%dim), pos_pc(space%dim), r, r2, threshold
1053 integer :: ip, err, icell
1054 complex(real64) :: zpot
1056 real(real64) :: aa, bb
1060 select type(species)
1064 call parse_variable(namespace,
'SpeciesProjectorSphereThreshold', 0.001_real64, threshold)
1070 do icell = 1, latt_iter%n_cells
1071 pos_pc = pos + latt_iter%get(icell)
1073 call mesh_r(mesh, ip, r, origin = pos_pc)
1075 vl(ip) = vl(ip) -species%get_zval()/
sqrt(r2+species%get_softening2())
1081 range = 5.0_real64 * latt%max_length()
1084 do icell = 1, latt_iter%n_cells
1085 pos_pc = pos + latt_iter%get(icell)
1087 call mesh_r(mesh, ip, r, origin = pos_pc, coords = xx)
1089 zpot = species%user_pot(space%dim, xx, r)
1090 vl(ip) = vl(ip) + real(zpot, real64)
1096 call dio_function_input(trim(species%get_filename()), namespace, space, mesh, vl, err)
1098 write(
message(1),
'(a)')
'Error loading file '//trim(species%get_filename())//
'.'
1099 write(
message(2),
'(a,i4)')
'Error code returned = ', err
1105 assert(.not. space%is_periodic())
1107 a1 = species%get_z()/(
m_two*species%radius()**3)
1108 a2 = species%get_z()/species%radius()
1109 rb2= species%radius()**2
1113 xx = mesh%x(:, ip) - pos(1:space%dim)
1116 if (r <= species%radius())
then
1117 vl(ip) = (a1*(r*r - rb2) - a2)
1119 vl(ip) = -species%get_z()/r
1128 density = species%get_density(mesh%box%bounding_box_l)
1133 r = abs(mesh%x(3, ip) - pos(3))
1135 if (r <= species%thickness()/
m_two)
then
1136 vl(ip) = a1 * (r * r / species%thickness() + species%thickness() /
m_four)
1145 assert(.not. space%is_periodic())
1149 r = norm2(mesh%x(:, ip) - pos)
1155 if (space%is_periodic())
then
1165 r2 = sum((mesh%x(:, ip) - pos)**2)*(species%get_z()*aa)**2
1176 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)
This module implements the curvilinear coordinates given in E.L. Briggs, D.J. Sullivan,...
type(debug_t), save, public debug
real(real64), parameter, public m_two
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.
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)
real(real64) pure function, public long_range_potential(r, sigma, z_val)
Evaluate the long-range potential at a given distance.
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_nlcc_grad_bare(species, space, latt, pos, mesh, grad_rho_core)
Returns the bare analytic gradient of the NLCC core density.
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_x)
Returns the (r-R_I)-weighted analytic gradient of the NLCC core density.
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)
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 ...