28 use,
intrinsic :: iso_fortran_env
66 type(mesh_t),
pointer :: mesh_p
67 real(real64),
allocatable :: rho_p(:)
68 real(real64),
allocatable :: grho_p(:, :)
69 real(real64) :: alpha2_p
70 real(real64),
pointer :: pos_p(:)
77 class(species_t),
target,
intent(in) :: species
78 type(namespace_t),
intent(in) :: namespace
79 class(space_t),
intent(in) :: space
80 type(lattice_vectors_t),
intent(in) :: latt
81 real(real64),
intent(in) :: pos(1:space%dim)
82 type(mesh_t),
intent(in) :: mesh
83 integer,
intent(in) :: spin_channels
84 real(real64),
intent(inout) :: rho(:, :)
86 integer :: isp, ip, in_points, icell
87 real(real64) :: rr, x, pos_pc(space%dim), nrm, rmax
88 real(real64) :: xx(space%dim), yy(space%dim), rerho, imrho
89 real(real64),
allocatable :: dorbital(:)
90 type(ps_t),
pointer :: ps
91 type(volume_t) :: volume
92 integer :: in_points_red
93 type(lattice_iterator_t) :: latt_iter
94 integer :: iorb, ii, nn, ll, mm
95 real(real64) :: radius, density
96 type(submesh_t) :: sphere
100 assert(spin_channels == 1 .or. spin_channels == 2)
105 select type (species)
117 do isp = 1, spin_channels
118 do iorb = 1, species%get_niwfs()
119 call species%get_iwf_ilm(iorb, isp, ii, ll, mm)
121 call species%get_iwf_n(iorb, isp, nn)
123 radius = species%get_iwf_radius(nn, isp)
125 radius = max(radius,
m_two*maxval(mesh%spacing))
127 call submesh_init(sphere, space, mesh, latt, pos, radius)
128 safe_allocate(dorbital(1:sphere%np))
135 dorbital(ip) = species%conf%occ(ii, isp)/real(2*ll+1, real64) *dorbital(ip)*dorbital(ip)
138 safe_deallocate_a(dorbital)
152 rmax = latt%max_length()
155 do icell = 1, latt_iter%n_cells
156 yy = latt_iter%get(icell)
158 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
164 rho(ip, 1) = rho(ip, 1) + rerho
170 if (spin_channels > 1)
then
172 rho(:, 2) = rho(:, 1)
176 do isp = 1, spin_channels
178 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
186 rmax = latt%max_length()
189 do icell = 1, latt_iter%n_cells
190 yy = latt_iter%get(icell)
192 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
198 rho(ip, 1) = rho(ip, 1) + rerho
202 if (spin_channels > 1)
then
203 rho(:, 1) =
m_half*rho(:, 1)
204 rho(:, 2) = rho(:, 1)
208 do isp = 1, spin_channels
210 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
217 call mesh_r(mesh, ip, rr, origin = pos)
218 if (rr <= species%radius())
then
219 in_points = in_points + 1
223 if (mesh%parallel_in_domains)
then
224 call mesh%mpi_grp%allreduce(in_points, in_points_red, 1, mpi_integer, mpi_sum)
225 in_points = in_points_red
228 if (in_points > 0)
then
231 if (mesh%use_curvilinear)
then
233 call mesh_r(mesh, ip, rr, origin = pos)
234 if (rr <= species%radius())
then
235 rho(ip, 1:spin_channels) = species%get_zval() / &
236 (mesh%vol_pp(ip) * real(in_points*spin_channels, real64) )
241 call mesh_r(mesh, ip, rr, origin = pos)
242 if (rr <= species%radius())
then
243 rho(ip, 1:spin_channels) = species%get_zval() / &
244 (mesh%vol_pp(1) * real(in_points * spin_channels, real64) )
251 density = species%get_density(mesh%box%bounding_box_l) / spin_channels
254 rr = abs(mesh%x(3, ip) - pos(3))
255 if (rr <= species%thickness() /
m_two)
then
256 rho(ip, 1:spin_channels) = density
267 assert(
allocated(ps%density))
270 do isp = 1, spin_channels
271 rmax = max(rmax, ps%density(isp)%x_threshold)
275 do icell = 1, latt_iter%n_cells
276 pos_pc = pos + latt_iter%get(icell)
278 call mesh_r(mesh, ip, rr, origin = pos_pc)
281 do isp = 1, spin_channels
283 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
294 do icell = 1, latt_iter%n_cells
295 pos_pc = pos + latt_iter%get(icell)
297 call mesh_r(mesh, ip, rr, origin = pos_pc)
302 do isp = 1, spin_channels
311 do isp = 1, spin_channels
315 rho(1:mesh%np, 1:spin_channels) = rho(1:mesh%np, 1:spin_channels)*species%get_zval()/nrm
325 do isp = 1, spin_channels
326 rho(1:mesh%np, isp) =
m_one
327 x = (species%get_zval()/real(spin_channels, real64) ) /
dmf_integrate(mesh, rho(:, isp))
328 rho(1:mesh%np, isp) = x * rho(1:mesh%np, isp)
338 class(
species_t),
target,
intent(in) :: species
340 real(real64),
intent(in) :: pos(:)
341 type(
mesh_t),
intent(in) :: mesh
342 integer,
intent(in) :: spin_channels
343 real(real64),
intent(inout) :: rho(:, :)
346 real(real64) :: rr, nrm
347 type(
ps_t),
pointer :: ps
361 assert(
allocated(ps%density))
364 do isp = 1, spin_channels
367 call mesh_r(mesh, ip, rr, origin = pos)
370 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
381 call mesh_r(mesh, ip, rr, origin = pos)
386 do isp = 1, spin_channels
394 do isp = 1, spin_channels
398 rho(1:mesh%np, 1:spin_channels) = rho(1:mesh%np, 1:spin_channels)*species%get_zval()/nrm
415 class(
species_t),
target,
intent(in) :: species
417 class(
space_t),
intent(in) :: space
419 real(real64),
intent(in) :: pos(1:space%dim)
420 type(
mesh_t),
intent(in) :: mesh
421 integer,
intent(in) :: spin_channels
422 real(real64),
intent(inout) :: drho(:, :)
425 real(real64) :: pos_pc(space%dim), range
426 type(
ps_t),
pointer :: ps
431 assert(spin_channels == 1 .or. spin_channels == 2)
443 range = ps%density_der(1)%x_threshold
444 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
447 do icell = 1, latt_iter%n_cells
448 pos_pc = pos + latt_iter%get(icell)
454 call messages_not_implemented(
'species_atom_density_derivative for non-pseudopotential species', namespace=namespace)
464 class(
species_t),
target,
intent(in) :: species
466 real(real64),
intent(in) :: pos(:)
467 type(
mesh_t),
intent(in) :: mesh
468 integer,
intent(in) :: spin_channels
469 real(real64),
intent(inout) :: drho(:, :)
473 type(
ps_t),
pointer :: ps
485 do isp = 1, spin_channels
488 call mesh_r(mesh, ip, rr, origin = pos)
491 drho(ip, isp) = drho(ip, isp) +
spline_eval(ps%density_der(isp), rr)
516 class(
species_t),
target,
intent(in) :: species
518 class(
space_t),
intent(in) :: space
520 real(real64),
intent(in) :: pos(1:space%dim)
521 type(
mesh_t),
intent(in) :: mesh
522 integer,
intent(in) :: spin_channels
523 real(real64),
intent(inout) :: drho(:, :, :)
525 integer :: isp, ip, icell, idir
526 real(real64) :: rr, pos_pc(space%dim), range, spline
527 type(
ps_t),
pointer :: ps
532 assert(spin_channels == 1 .or. spin_channels == 2)
544 range = ps%density_der(1)%x_threshold
545 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
548 do icell = 1, latt_iter%n_cells
549 pos_pc = pos + latt_iter%get(icell)
552 call mesh_r(mesh, ip, rr, origin = pos_pc)
555 do isp = 1, spin_channels
559 if(abs(spline) < 1e-150_real64) cycle
561 do idir = 1, space%dim
562 drho(ip, isp, idir) = drho(ip, isp, idir) - spline*(mesh%x(idir, ip) - pos_pc(idir))/rr
586 class(
species_t),
target,
intent(in) :: species
588 class(
space_t),
intent(in) :: space
590 real(real64),
target,
intent(in) :: pos(1:space%dim)
591 class(
mesh_t),
target,
intent(in) :: mesh
592 real(real64),
intent(out) :: rho(:)
593 type(
submesh_t),
optional,
target,
intent(inout) :: sphere_inout
594 real(real64),
optional,
intent(inout) :: nlr_x(:,:)
598 real(real64) :: startval(space%dim)
599 real(real64) :: delta, alpha, xx(space%dim), yy(space%dim), rr, imrho1, rerho
600 real(real64) :: dist2_min
601 integer :: icell, ipos, ip, idir, rankmin
603 type(
ps_t),
pointer :: ps
607 logical :: have_point
608 real(real64),
allocatable :: rho_sphere(:)
609 real(real64),
parameter :: threshold = 1e-6_real64
610 real(real64) :: norm_factor, range, radius, radius_nlr, radius_vl
616 if(
present(nlr_x))
then
617 assert(species%is_ps())
620 select type (species)
624 if (
present(sphere_inout))
then
625 radius_vl = ps%vl%x_threshold*1.05_real64
626 radius = max(radius_nlr, radius_vl)
627 call submesh_init(sphere_inout, space, mesh, latt, pos, radius)
628 sphere => sphere_inout
631 call submesh_init(sphere_local, space, mesh, latt, pos, radius)
632 sphere => sphere_local
635 safe_allocate(rho_sphere(1:sphere%np))
636 if (.not.
present(sphere_inout) .and. sphere%np > 0)
then
637 call lalg_copy(sphere%np, sphere%r, rho_sphere)
641 if(sphere%r(ip) <= radius_nlr)
then
653 norm_factor = abs(species%get_zval()/
dsm_integrate(mesh, sphere, rho_sphere))
655 rho(sphere%map(ip)) = rho(sphere%map(ip)) + norm_factor*rho_sphere(ip)
658 if (
present(nlr_x))
then
659 do idir = 1, space%dim
661 nlr_x(sphere%map(ip), idir) = nlr_x(sphere%map(ip), idir) + norm_factor*rho_sphere(ip)*sphere%rel_x(idir, ip)
666 safe_deallocate_a(rho_sphere)
668 if ( .not.
present(sphere_inout) )
then
679 if (mesh%mpi_grp%rank /= rankmin) have_point = .false.
682 if (mesh%use_curvilinear)
then
683 rho(ipos) = -species%get_z()/mesh%vol_pp(ipos)
685 rho(ipos) = -species%get_z()/mesh%vol_pp(1)
689 write(
message(1),
'(3a,f5.2,3a)') &
690 "Info: species_full_delta species ", trim(species%get_label()), &
698 if (space%is_periodic())
then
704 if (mesh%use_curvilinear)
then
714 safe_allocate(rho_p(1:mesh%np))
715 safe_allocate(grho_p(1:mesh%np, 1:space%dim))
721 delta = mesh%spacing(1)
722 alpha =
sqrt(
m_two)*species%get_sigma()*delta
726 startval(1:space%dim) = pos
734 write(
message(1),
'(a)')
'Root finding in species_get_density did not converge.'
738 if(
debug%info .and. space%dim == 3)
then
739 write(
message(1),
'(a,3(f6.3,a))')
'Debug: Gaussian charge position (', xx(1),
', ', xx(2),
', ', xx(3),
')'
744 rho = -species%get_z()*rho_p
748 safe_deallocate_a(grho_p)
749 safe_deallocate_a(rho_p)
760 range = latt%max_length()
764 do icell = 1, latt_iter%n_cells
765 yy = latt_iter%get(icell)
767 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
773 rho(ip) = rho(ip) - rerho
781 range = latt%max_length()
785 do icell = 1, latt_iter%n_cells
786 yy = latt_iter%get(icell)
788 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
794 rho(ip) = rho(ip) - rerho
799 rho(1:mesh%np) = rr * rho(1:mesh%np)
811 subroutine func(xin, ff, jacobian)
812 real(real64),
intent(in) :: xin(:)
813 real(real64),
intent(out) :: ff(:), jacobian(:,:)
815 real(real64),
allocatable :: xrho(:)
816 integer :: idir, jdir, dim, ip
823 safe_allocate(xrho(1:mesh_p%np))
829 xrho(ip) = rho_p(ip) * mesh_p%x_t(ip, idir)
839 xrho(ip) = grho_p(ip, jdir) * mesh_p%x_t(ip, idir)
845 safe_deallocate_a(xrho)
850 subroutine species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
851 class(
species_t),
target,
intent(in) :: species
852 class(
space_t),
intent(in) :: space
854 real(real64),
intent(in) :: pos(1:space%dim)
855 class(
mesh_t),
intent(in) :: mesh
856 real(real64),
intent(inout) :: rho_core(:)
857 logical,
optional,
intent(in) :: accumulate
859 real(real64) :: center(space%dim), rr
862 type(
ps_t),
pointer :: ps
873 do icell = 1, latt_iter%n_cells
874 center = pos + latt_iter%get(icell)
876 rr = norm2(mesh%x(1:space%dim, ip) - center)
878 rho_core(ip) = rho_core(ip) +
spline_eval(ps%core, rr)
892 subroutine getrho(dim, xin)
893 integer,
intent(in) :: dim
894 real(real64),
intent(in) :: xin(1:dim)
897 real(real64) :: r2, chi(dim), norm, threshold
903 threshold = -
log(0.001_real64)*alpha2_p
907 chi(1:dim) = mesh_p%x(1:dim, ip)
908 r2 = sum((chi - xin(1:dim))**2)
910 if (r2 < threshold)
then
911 rho_p(ip) =
exp(-r2/alpha2_p)
917 grho_p(ip, idir) = (chi(idir) - xin(idir)) * rho_p(ip)
932 class(
species_t),
target,
intent(in) :: species
934 class(
space_t),
intent(in) :: space
936 real(real64),
intent(in) :: pos(1:space%dim)
937 type(
mesh_t),
intent(in) :: mesh
938 real(real64),
intent(out) :: vl(:)
940 real(real64) :: a1, a2, Rb2, range, density
941 real(real64) :: xx(space%dim), pos_pc(space%dim), r, r2, threshold
942 integer :: ip, err, icell
943 complex(real64) :: zpot
945 real(real64) :: aa, bb
953 call parse_variable(namespace,
'SpeciesProjectorSphereThreshold', 0.001_real64, threshold)
959 do icell = 1, latt_iter%n_cells
960 pos_pc = pos + latt_iter%get(icell)
962 call mesh_r(mesh, ip, r, origin = pos_pc)
964 vl(ip) = vl(ip) -species%get_zval()/
sqrt(r2+species%get_softening2())
970 range = 5.0_real64 * latt%max_length()
973 do icell = 1, latt_iter%n_cells
974 pos_pc = pos + latt_iter%get(icell)
976 call mesh_r(mesh, ip, r, origin = pos_pc, coords = xx)
978 zpot = species%user_pot(space%dim, xx, r)
979 vl(ip) = vl(ip) + real(zpot, real64)
985 call dio_function_input(trim(species%get_filename()), namespace, space, mesh, vl, err)
987 write(
message(1),
'(a)')
'Error loading file '//trim(species%get_filename())//
'.'
988 write(
message(2),
'(a,i4)')
'Error code returned = ', err
994 assert(.not. space%is_periodic())
996 a1 = species%get_z()/(
m_two*species%radius()**3)
997 a2 = species%get_z()/species%radius()
998 rb2= species%radius()**2
1002 xx = mesh%x(:, ip) - pos(1:space%dim)
1005 if (r <= species%radius())
then
1006 vl(ip) = (a1*(r*r - rb2) - a2)
1008 vl(ip) = -species%get_z()/r
1017 density = species%get_density(mesh%box%bounding_box_l)
1022 r = abs(mesh%x(3, ip) - pos(3))
1024 if (r <= species%thickness()/
m_two)
then
1025 vl(ip) = a1 * (r * r / species%thickness() + species%thickness() /
m_four)
1034 assert(.not. space%is_periodic())
1038 r = norm2(mesh%x(:, ip) - pos)
1044 if (space%is_periodic())
then
1054 r2 = sum((mesh%x(:, ip) - pos)**2)*(species%get_z()*aa)**2
1065 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 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_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_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 ...