28 use,
intrinsic :: iso_fortran_env
65 type(mesh_t),
pointer :: mesh_p
66 real(real64),
allocatable :: rho_p(:)
67 real(real64),
allocatable :: grho_p(:, :)
68 real(real64) :: alpha2_p
69 real(real64),
pointer :: pos_p(:)
76 class(species_t),
target,
intent(in) :: species
77 type(namespace_t),
intent(in) :: namespace
78 class(space_t),
intent(in) :: space
79 type(lattice_vectors_t),
intent(in) :: latt
80 real(real64),
intent(in) :: pos(1:space%dim)
81 type(mesh_t),
intent(in) :: mesh
82 integer,
intent(in) :: spin_channels
83 real(real64),
intent(inout) :: rho(:, :)
85 integer :: isp, ip, in_points, icell
86 real(real64) :: rr, x, pos_pc(space%dim), nrm, rmax
87 real(real64) :: xx(space%dim), yy(space%dim), rerho, imrho
88 real(real64),
allocatable :: dorbital(:)
89 type(ps_t),
pointer :: ps
90 type(volume_t) :: volume
91 integer :: in_points_red
92 type(lattice_iterator_t) :: latt_iter
93 integer :: iorb, ii, nn, ll, mm
94 real(real64) :: radius, density
95 type(submesh_t) :: sphere
99 assert(spin_channels == 1 .or. spin_channels == 2)
104 select type (species)
116 do isp = 1, spin_channels
117 do iorb = 1, species%get_niwfs()
118 call species%get_iwf_ilm(iorb, isp, ii, ll, mm)
120 call species%get_iwf_n(iorb, isp, nn)
122 radius = species%get_iwf_radius(nn, isp)
124 radius = max(radius,
m_two*maxval(mesh%spacing))
126 call submesh_init(sphere, space, mesh, latt, pos, radius)
127 safe_allocate(dorbital(1:sphere%np))
134 dorbital(ip) = species%conf%occ(ii, isp)/real(2*ll+1, real64) *dorbital(ip)*dorbital(ip)
137 safe_deallocate_a(dorbital)
151 rmax = latt%max_length()
154 do icell = 1, latt_iter%n_cells
155 yy = latt_iter%get(icell)
157 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
163 rho(ip, 1) = rho(ip, 1) + rerho
169 if (spin_channels > 1)
then
171 rho(:, 2) = rho(:, 1)
175 do isp = 1, spin_channels
179 rho(ip, isp) = x * rho(ip, isp)
189 rmax = latt%max_length()
192 do icell = 1, latt_iter%n_cells
193 yy = latt_iter%get(icell)
195 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
201 rho(ip, 1) = rho(ip, 1) + rerho
205 if (spin_channels > 1)
then
206 rho(:, 1) =
m_half*rho(:, 1)
207 rho(:, 2) = rho(:, 1)
211 do isp = 1, spin_channels
215 rho(ip, isp) = x * rho(ip, isp)
224 call mesh_r(mesh, ip, rr, origin = pos)
225 if (rr <= species%radius())
then
226 in_points = in_points + 1
230 if (mesh%parallel_in_domains)
then
231 call mesh%mpi_grp%allreduce(in_points, in_points_red, 1, mpi_integer, mpi_sum)
232 in_points = in_points_red
235 if (in_points > 0)
then
238 if (mesh%use_curvilinear)
then
240 call mesh_r(mesh, ip, rr, origin = pos)
241 if (rr <= species%radius())
then
242 rho(ip, 1:spin_channels) = species%get_zval() / &
243 (mesh%vol_pp(ip) * real(in_points*spin_channels, real64) )
248 call mesh_r(mesh, ip, rr, origin = pos)
249 if (rr <= species%radius())
then
250 rho(ip, 1:spin_channels) = species%get_zval() / &
251 (mesh%vol_pp(1) * real(in_points * spin_channels, real64) )
258 density = species%get_density(mesh%box%bounding_box_l) / spin_channels
261 rr = abs(mesh%x(3, ip) - pos(3))
262 if (rr <= species%thickness() /
m_two)
then
263 rho(ip, 1:spin_channels) = density
274 assert(
allocated(ps%density))
277 do isp = 1, spin_channels
278 rmax = max(rmax, ps%density(isp)%x_threshold)
282 do icell = 1, latt_iter%n_cells
283 pos_pc = pos + latt_iter%get(icell)
285 call mesh_r(mesh, ip, rr, origin = pos_pc)
288 do isp = 1, spin_channels
290 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
301 do icell = 1, latt_iter%n_cells
302 pos_pc = pos + latt_iter%get(icell)
304 call mesh_r(mesh, ip, rr, origin = pos_pc)
309 do isp = 1, spin_channels
318 do isp = 1, spin_channels
322 do isp = 1, spin_channels
323 call lalg_scal(mesh%np, species%get_zval()/nrm, rho(:, isp))
334 do isp = 1, spin_channels
335 rho(1:mesh%np, isp) =
m_one
336 x = (species%get_zval()/real(spin_channels, real64) ) /
dmf_integrate(mesh, rho(:, isp))
337 rho(1:mesh%np, isp) = x
347 class(
species_t),
target,
intent(in) :: species
349 real(real64),
intent(in) :: pos(:)
350 type(
mesh_t),
intent(in) :: mesh
351 integer,
intent(in) :: spin_channels
352 real(real64),
intent(inout) :: rho(:, :)
355 real(real64) :: rr, nrm
356 type(
ps_t),
pointer :: ps
370 assert(
allocated(ps%density))
373 do isp = 1, spin_channels
376 call mesh_r(mesh, ip, rr, origin = pos)
379 rho(ip, isp) = rho(ip, isp) +
spline_eval(ps%density(isp), rr)
390 call mesh_r(mesh, ip, rr, origin = pos)
395 do isp = 1, spin_channels
403 do isp = 1, spin_channels
407 do isp = 1, spin_channels
408 call lalg_scal(mesh%np, species%get_zval()/nrm, rho(:, isp))
425 class(
species_t),
target,
intent(in) :: species
427 real(real64),
intent(in) :: pos(:)
429 integer,
intent(in) :: spin_channels
430 real(real64),
intent(inout) :: drho(:, :)
434 type(
ps_t),
pointer :: ps
446 do isp = 1, spin_channels
449 call mesh_r(mesh, ip, rr, origin = pos)
452 drho(ip, isp) = drho(ip, isp) +
spline_eval(ps%density_der(isp), rr)
477 class(
species_t),
target,
intent(in) :: species
479 class(
space_t),
intent(in) :: space
481 real(real64),
intent(in) :: pos(1:space%dim)
482 type(
mesh_t),
intent(in) :: mesh
483 integer,
intent(in) :: spin_channels
484 real(real64),
intent(inout) :: drho(:, :, :)
486 integer :: isp, ip, icell, idir
487 real(real64) :: rr, pos_pc(space%dim), range, spline
488 type(
ps_t),
pointer :: ps
493 assert(spin_channels == 1 .or. spin_channels == 2)
505 range = ps%density_der(1)%x_threshold
506 if (spin_channels == 2) range = max(range, ps%density_der(2)%x_threshold)
509 do icell = 1, latt_iter%n_cells
510 pos_pc = pos + latt_iter%get(icell)
513 call mesh_r(mesh, ip, rr, origin = pos_pc)
516 do isp = 1, spin_channels
520 if(abs(spline) < 1e-150_real64) cycle
522 do idir = 1, space%dim
523 drho(ip, isp, idir) = drho(ip, isp, idir) - spline*(mesh%x(idir, ip) - pos_pc(idir))/rr
547 class(
species_t),
target,
intent(in) :: species
549 class(
space_t),
intent(in) :: space
551 real(real64),
target,
intent(in) :: pos(1:space%dim)
552 class(
mesh_t),
target,
intent(in) :: mesh
553 real(real64),
intent(out) :: rho(:)
554 type(
submesh_t),
optional,
target,
intent(inout) :: sphere_inout
555 real(real64),
optional,
intent(inout) :: nlr_x(:,:)
559 real(real64) :: startval(space%dim)
560 real(real64) :: delta, alpha, xx(space%dim), yy(space%dim), rr, imrho1, rerho
561 real(real64) :: dist2_min
562 integer :: icell, ipos, ip, idir, rankmin
564 type(
ps_t),
pointer :: ps
568 logical :: have_point
569 real(real64),
allocatable :: rho_sphere(:)
570 real(real64),
parameter :: threshold = 1e-6_real64
571 real(real64) :: norm_factor, range, radius, radius_nlr, radius_vl
577 if(
present(nlr_x))
then
578 assert(species%is_ps())
581 select type (species)
585 if (
present(sphere_inout))
then
586 radius_vl = ps%vl%x_threshold*1.05_real64
587 radius = max(radius_nlr, radius_vl)
588 call submesh_init(sphere_inout, space, mesh, latt, pos, radius)
589 sphere => sphere_inout
592 call submesh_init(sphere_local, space, mesh, latt, pos, radius)
593 sphere => sphere_local
596 safe_allocate(rho_sphere(1:sphere%np))
597 if (.not.
present(sphere_inout) .and. sphere%np > 0)
then
598 call lalg_copy(sphere%np, sphere%r, rho_sphere)
602 if(sphere%r(ip) <= radius_nlr)
then
614 norm_factor = abs(species%get_zval()/
dsm_integrate(mesh, sphere, rho_sphere))
616 rho(sphere%map(ip)) = rho(sphere%map(ip)) + norm_factor*rho_sphere(ip)
619 if (
present(nlr_x))
then
620 do idir = 1, space%dim
622 nlr_x(sphere%map(ip), idir) = nlr_x(sphere%map(ip), idir) + norm_factor*rho_sphere(ip)*sphere%rel_x(idir, ip)
627 safe_deallocate_a(rho_sphere)
629 if ( .not.
present(sphere_inout) )
then
640 if (mesh%mpi_grp%rank /= rankmin) have_point = .false.
643 if (mesh%use_curvilinear)
then
644 rho(ipos) = -species%get_z()/mesh%vol_pp(ipos)
646 rho(ipos) = -species%get_z()/mesh%vol_pp(1)
650 write(
message(1),
'(3a,f5.2,3a)') &
651 "Info: species_full_delta species ", trim(species%get_label()), &
659 if (space%is_periodic())
then
665 if (mesh%use_curvilinear)
then
675 safe_allocate(rho_p(1:mesh%np))
676 safe_allocate(grho_p(1:mesh%np, 1:space%dim))
682 delta = mesh%spacing(1)
683 alpha =
sqrt(
m_two)*species%get_sigma()*delta
687 startval(1:space%dim) = pos
695 write(
message(1),
'(a)')
'Root finding in species_get_density did not converge.'
699 if(
debug%info .and. space%dim == 3)
then
700 write(
message(1),
'(a,3(f6.3,a))')
'Debug: Gaussian charge position (', xx(1),
', ', xx(2),
', ', xx(3),
')'
705 rho = -species%get_z()*rho_p
709 safe_deallocate_a(grho_p)
710 safe_deallocate_a(rho_p)
721 range = latt%max_length()
725 do icell = 1, latt_iter%n_cells
726 yy = latt_iter%get(icell)
728 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
734 rho(ip) = rho(ip) - rerho
742 range = latt%max_length()
746 do icell = 1, latt_iter%n_cells
747 yy = latt_iter%get(icell)
749 call mesh_r(mesh, ip, rr, origin = pos, coords = xx)
755 rho(ip) = rho(ip) - rerho
772 subroutine func(xin, ff, jacobian)
773 real(real64),
intent(in) :: xin(:)
774 real(real64),
intent(out) :: ff(:), jacobian(:,:)
776 real(real64),
allocatable :: xrho(:)
777 integer :: idir, jdir, dim, ip
784 safe_allocate(xrho(1:mesh_p%np))
790 xrho(ip) = rho_p(ip) * mesh_p%x_t(ip, idir)
800 xrho(ip) = grho_p(ip, jdir) * mesh_p%x_t(ip, idir)
806 safe_deallocate_a(xrho)
811 subroutine species_get_nlcc(species, space, latt, pos, mesh, rho_core, accumulate)
812 class(
species_t),
target,
intent(in) :: species
813 class(
space_t),
intent(in) :: space
815 real(real64),
intent(in) :: pos(1:space%dim)
816 class(
mesh_t),
intent(in) :: mesh
817 real(real64),
intent(inout) :: rho_core(:)
818 logical,
optional,
intent(in) :: accumulate
820 real(real64) :: center(space%dim), rr
823 type(
ps_t),
pointer :: ps
834 do icell = 1, latt_iter%n_cells
835 center = pos + latt_iter%get(icell)
837 rr = norm2(mesh%x(1:space%dim, ip) - center)
839 rho_core(ip) = rho_core(ip) +
spline_eval(ps%core, rr)
853 subroutine getrho(dim, xin)
854 integer,
intent(in) :: dim
855 real(real64),
intent(in) :: xin(1:dim)
858 real(real64) :: r2, chi(dim), norm, threshold
866 threshold = -
log(0.0001_real64)*alpha2_p
870 chi(1:dim) = mesh_p%x(1:dim, ip)
871 r2 = sum((chi - xin(1:dim))**2)
873 if (r2 < threshold)
then
874 rho_p(ip) =
exp(-r2/alpha2_p)
880 grho_p(ip, idir) = (chi(idir) - xin(idir)) * rho_p(ip)
895 class(
species_t),
target,
intent(in) :: species
897 class(
space_t),
intent(in) :: space
899 real(real64),
intent(in) :: pos(1:space%dim)
900 type(
mesh_t),
intent(in) :: mesh
901 real(real64),
intent(out) :: vl(:)
903 real(real64) :: a1, a2, Rb2, range, density
904 real(real64) :: xx(space%dim), pos_pc(space%dim), r, r2, threshold
905 integer :: ip, err, icell
906 complex(real64) :: zpot
908 real(real64) :: aa, bb
916 call parse_variable(namespace,
'SpeciesProjectorSphereThreshold', 0.001_real64, threshold)
922 do icell = 1, latt_iter%n_cells
923 pos_pc = pos + latt_iter%get(icell)
925 call mesh_r(mesh, ip, r, origin = pos_pc)
927 vl(ip) = vl(ip) -species%get_zval()/
sqrt(r2+species%get_softening2())
933 range = 5.0_real64 * latt%max_length()
936 do icell = 1, latt_iter%n_cells
937 pos_pc = pos + latt_iter%get(icell)
939 call mesh_r(mesh, ip, r, origin = pos_pc, coords = xx)
941 zpot = species%user_pot(space%dim, xx, r)
942 vl(ip) = vl(ip) + real(zpot, real64)
950 write(
message(1),
'(a)')
'Error loading file '//trim(species%get_filename())//
'.'
951 write(
message(2),
'(a,i4)')
'Error code returned = ', err
957 assert(.not. space%is_periodic())
959 a1 = species%get_z()/(
m_two*species%radius()**3)
960 a2 = species%get_z()/species%radius()
961 rb2= species%radius()**2
965 xx = mesh%x(:, ip) - pos(1:space%dim)
968 if (r <= species%radius())
then
969 vl(ip) = (a1*(r*r - rb2) - a2)
971 vl(ip) = -species%get_z()/r
980 density = species%get_density(mesh%box%bounding_box_l)
985 r = abs(mesh%x(3, ip) - pos(3))
987 if (r <= species%thickness()/
m_two)
then
988 vl(ip) = a1 * (r * r / species%thickness() + species%thickness() /
m_four)
997 assert(.not. space%is_periodic())
1001 r = norm2(mesh%x(:, ip) - pos)
1007 if (space%is_periodic())
then
1017 r2 = sum((mesh%x(:, ip) - pos)**2)*(species%get_z()*aa)**2
1028 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)
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 ...