70 class(mesh_t),
intent(in) :: mesh
71 type(states_elec_dim_t),
intent(in) :: std
72 real(real64),
intent(in) :: rho(:,:)
73 real(real64),
intent(out) :: md(:,:)
79 select case (std%ispin)
87 md(ip, 3) = rho(ip, 1) - rho(ip, 2)
94 md(ip, 1) =
m_two*rho(ip, 3)
95 md(ip, 2) = -
m_two*rho(ip, 4)
96 md(ip, 3) = rho(ip, 1) - rho(ip, 2)
107 class(mesh_t),
intent(in) :: mesh
108 type(states_elec_t),
intent(in) :: st
109 real(real64),
intent(in) :: rho(:,:)
110 real(real64),
intent(out) :: mm(3)
112 real(real64),
allocatable :: md(:,:)
114 push_sub(states_elec_magnetic_moment)
116 safe_allocate(md(1:mesh%np, 1:3))
121 safe_deallocate_a(md)
123 pop_sub(states_elec_magnetic_moment)
130 type(grid_t),
intent(in) :: gr
131 type(states_elec_t),
intent(in) :: st
132 type(phase_t),
intent(in) :: phase
133 type(epot_t),
intent(in) :: ep
134 type(ions_t),
intent(in) :: ions
135 real(real64),
intent(in) :: lmm_r
136 logical,
optional,
intent(in) :: calc_orb_moments
137 integer,
optional,
intent(in) :: iunit
138 type(namespace_t),
optional,
intent(in) :: namespace
141 real(real64) :: mm(max(gr%box%dim, 3))
142 real(real64),
allocatable :: lmm(:,:)
147 safe_allocate(lmm(1:max(gr%box%dim, 3), 1:ions%natoms))
150 message(1) =
'Total Spin Magnetic Moment:'
153 write(
message(1),
'(a,f10.6)')
' mz = ', mm(3)
155 else if (st%d%ispin ==
spinors)
then
156 write(
message(1),
'(1x,3(a,f10.6,3x))')
'mx = ', mm(1),
'my = ', mm(2),
'mz = ', mm(3)
160 write(
message(1),
'(a,a,a,f7.3,a)')
'Local Spin Magnetic Moments (sphere radius [', &
166 do ia = 1, ions%natoms
167 write(
message(1),
'(i4,a10,f15.6)') ia, trim(ions%atom(ia)%species%get_label()), lmm(3, ia)
170 else if (st%d%ispin ==
spinors)
then
171 write(
message(1),
'(a,8x,13x,a,13x,a,13x,a)')
' Ion',
'mx',
'my',
'mz'
173 do ia = 1, ions%natoms
174 write(
message(1),
'(i4,a10,9f15.6)') ia, trim(ions%atom(ia)%species%get_label()), lmm(:, ia)
182 if (
mpi_world%is_root())
write(iunit,
'(1x)')
186 write(
message(1),
'(a,a,a,f7.3,a)')
'Local Orbital Moments (sphere radius [', &
189 write(
message(1),
'(a,8x,13x,a,13x,a,13x,a)')
' Ion',
'Lx',
'Ly',
'Lz'
191 do ia = 1, ions%natoms
192 write(
message(1),
'(i4,a10,9f15.6)') ia, trim(ions%atom(ia)%species%get_label()), lmm(:, ia)
198 safe_deallocate_a(lmm)
205 class(
mesh_t),
intent(in) :: mesh
207 type(
ions_t),
intent(in) :: ions
209 real(real64),
intent(in) :: rho(:,:)
210 real(real64),
intent(in) :: rr
211 real(real64),
intent(out) :: lmm(max(mesh%box%dim, 3), ions%natoms)
213 integer :: ia, idir, is
214 real(real64),
allocatable :: md(:, :)
216 real(real64) :: cosqr, sinqr
217 complex(real64),
allocatable :: phase_spiral(:)
221 safe_allocate(md(1:mesh%np, 1:max(mesh%box%dim, 3)))
225 do ia = 1, ions%natoms
226 call submesh_init(sphere, ions%space, mesh, ions%latt, ions%pos(:, ia), rr)
228 if (boundaries%spiral)
then
229 safe_allocate(phase_spiral(1:sphere%np))
231 phase_spiral(is) =
exp(+
m_zi*sum((sphere%rel_x(:,is) + sphere%center - mesh%x(:, sphere%map(is))) &
232 *boundaries%spiral_q(1:mesh%box%dim)))
235 if (mesh%box%dim>= 3)
then
241 cosqr = real(phase_spiral(is), real64)
242 sinqr = aimag(phase_spiral(is))
243 lmm(1,ia) = lmm(1,ia)+md(sphere%map(is),1)*cosqr - md(sphere%map(is),2)*sinqr
244 lmm(2,ia) = lmm(2,ia)+md(sphere%map(is),1)*sinqr + md(sphere%map(is),2)*cosqr
246 lmm(1,ia) = lmm(1,ia)*mesh%volume_element
247 lmm(2,ia) = lmm(2,ia)*mesh%volume_element
250 assert(.not. boundaries%spiral)
253 safe_deallocate_a(phase_spiral)
255 do idir = 1, max(mesh%box%dim, 3)
263 call mesh%allreduce(lmm)
265 safe_deallocate_a(md)
282 type(
grid_t),
intent(in) :: gr
284 type(
phase_t),
intent(in) :: phase
285 type(
epot_t),
intent(in) :: ep
286 type(
ions_t),
intent(in) :: ions
287 real(real64),
intent(in) :: rho(:,:)
288 real(real64),
intent(in) :: rr
289 real(real64),
intent(out) :: lom(3, ions%natoms)
291 integer :: ia, idir, is, map_ip, ibatch, idim, ist, ib, ik
296 complex(real64),
allocatable :: psi(:,:), gf(:,:,:), gf_nl(:,:,:)
297 complex(real64) :: acc(3), acc_nl(3)
298 real(real64) :: x1, x2, x3, factor
303 assert(ions%space%dim == 3)
304 assert(.not. gr%use_curvilinear)
308 safe_allocate(psi(1:gr%np_part, 1:st%d%dim))
309 safe_allocate(gf(1:gr%np, 1:st%d%dim, 1:gr%der%dim))
310 safe_allocate(gf_nl(1:gr%np, 1:st%d%dim, 1:gr%der%dim))
311 safe_allocate_type_array(
wfs_elec_t, gpsib, (1:gr%der%dim))
313 do ik = st%d%kpt%start, st%d%kpt%end
314 do ib = st%group%block_start, st%group%block_end
316 call phase%copy_and_set_phase(gr, st%d%kpt, st%group%psib(ib, ik), epsib)
321 do ibatch = 1, epsib%nst
322 ist = st%group%psib(ib, ik)%ist(ibatch)
323 factor = st%kweights(ik)*st%occ(ist, ik)
335 do ia = 1, ions%natoms
336 call submesh_init(sphere, ions%space, gr, ions%latt, ions%pos(:, ia), rr)
339 call zprojector_commute_r(ep%proj(ia), gr, gr%der%boundaries, st%d%dim, 1, ik, psi, gf_nl(:, :, 1))
340 call zprojector_commute_r(ep%proj(ia), gr, gr%der%boundaries, st%d%dim, 2, ik, psi, gf_nl(:, :, 2))
341 call zprojector_commute_r(ep%proj(ia), gr, gr%der%boundaries, st%d%dim, 3, ik, psi, gf_nl(:, :, 3))
345 do idim = 1, st%d%dim
347 map_ip = sphere%map(is)
348 x1 = sphere%rel_x(1, is)
349 x2 = sphere%rel_x(2, is)
350 x3 = sphere%rel_x(3, is)
352 acc(1) = acc(1) + conjg(psi(map_ip, idim)) * (x2 * gf(map_ip, idim, 3) - x3 * gf(map_ip, idim, 2))
353 acc(2) = acc(2) + conjg(psi(map_ip, idim)) * (x3 * gf(map_ip, idim, 1) - x1 * gf(map_ip, idim, 3))
354 acc(3) = acc(3) + conjg(psi(map_ip, idim)) * (x1 * gf(map_ip, idim, 2) - x2 * gf(map_ip, idim, 1))
356 acc_nl(:) = acc_nl(:) + conjg(psi(map_ip, idim)) * gf_nl(map_ip, idim, :)
362 lom(:, ia) = lom(:, ia) + factor * gr%volume_element * (aimag(acc) +
dcross_product(ions%pos(:, ia), aimag(acc_nl)))
366 do idir = 1, gr%der%dim
367 call gpsib(idir)%end()
374 call gr%allreduce(lom)
375 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
379 safe_deallocate_a(psi)
380 safe_deallocate_a(gf)
381 safe_deallocate_a(gf_nl)
382 safe_deallocate_a(gpsib)
390 class(
mesh_t),
intent(in) :: mesh
392 real(real64),
intent(in) :: qq(:)
393 complex(real64),
intent(out) :: trans_mag(6)
396 complex(real64),
allocatable :: tmp(:,:)
397 real(real64),
allocatable :: md(:, :)
398 complex(real64) :: expqr
404 safe_allocate(tmp(1:mesh%np, 1:6))
405 safe_allocate(md(1:mesh%np, 1:max(mesh%box%dim, 3)))
409 expqr =
exp(-
m_zi*sum(mesh%x(1:mesh%box%dim, ip)*qq(1:mesh%box%dim)))
410 tmp(ip,1) = expqr*md(ip,1)
411 tmp(ip,2) = expqr*md(ip,2)
412 tmp(ip,3) = expqr*md(ip,3)
413 tmp(ip,4) = conjg(expqr)*md(ip,1)
414 tmp(ip,5) = conjg(expqr)*md(ip,2)
415 tmp(ip,6) = conjg(expqr)*md(ip,3)
420 safe_deallocate_a(md)
421 safe_deallocate_a(tmp)
432 subroutine magnetic_induced(namespace, gr, st, psolver, kpoints, a_ind, b_ind)
434 type(
grid_t),
intent(in) :: gr
438 real(real64),
contiguous,
intent(out) :: a_ind(:, :)
439 real(real64),
contiguous,
intent(out) :: b_ind(:, :)
444 real(real64),
allocatable :: jj(:, :, :)
457 safe_allocate(jj(1:gr%np_part, 1:gr%der%dim, 1:st%d%nspin))
461 if (st%d%nspin > 1)
then
462 do idir = 1, gr%der%dim
463 jj(:, idir, 1) = jj(:, idir, 1) + jj(:, idir, 2)
468 do idir = 1, gr%der%dim
469 call dpoisson_solve(psolver, namespace, a_ind(:, idir), jj(:, idir, 1))
478 safe_deallocate_a(jj)
483 integer,
intent(in) :: iunit
485 real(real64),
intent(in) :: vxc(:,:)
488 real(real64),
allocatable :: torque(:,:)
489 real(real64) :: tt(3)
493 safe_allocate(torque(1:mesh%np, 1:3))
499 if (st%system_grp%is_root())
then
500 write(iunit,
'(a)')
'Total xc torque:'
501 write(iunit,
'(1x,3(a,es10.3,3x))')
'Tx = ', tt(1),
'Ty = ', tt(2),
'Tz = ', tt(3)
504 safe_deallocate_a(torque)
511 class(
mesh_t),
intent(in) :: mesh
512 real(real64),
intent(in) :: vxc(:,:)
514 real(real64),
intent(out) :: torque(:,:)
516 real(real64) :: mag(3), bxc(3)
524 mag(1) =
m_two * st%rho(ip, 3)
525 mag(2) = -
m_two * st%rho(ip, 4)
526 mag(3) = st%rho(ip, 1) - st%rho(ip, 2)
528 bxc(2) =
m_two * vxc(ip, 4)
529 bxc(3) = -(vxc(ip, 1) - vxc(ip, 2))
530 torque(ip, 1) = mag(2) * bxc(3) - mag(3) * bxc(2)
531 torque(ip, 2) = mag(3) * bxc(1) - mag(1) * bxc(3)
532 torque(ip, 3) = mag(1) * bxc(2) - mag(2) * bxc(1)
scales a vector by a constant
double exp(double __x) __attribute__((__nothrow__
This module implements common operations on batches of mesh functions.
Module implementing boundary conditions in Octopus.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_curl(der, ff, op_ff, ghost_update, set_bc)
apply the curl operator to a vector of mesh functions
subroutine, public zderivatives_batch_grad(der, ffb, opffb, ghost_update, set_bc, to_cartesian, factor)
apply the gradient to a batch of mesh functions
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
integer, parameter, public spin_polarized
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
complex(real64), parameter, public m_zi
real(real64), parameter, public m_epsilon
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public magnetic_local_moments(mesh, st, ions, boundaries, rho, rr, lmm)
subroutine magnetic_orbital_moments(gr, st, phase, ep, ions, rho, rr, lom)
@bief Computes orbital moments around the atoms in the GIPAW gauge
subroutine, public calc_xc_torque(mesh, vxc, st, torque)
subroutine, public magnetic_moment(mesh, st, rho, mm)
subroutine, public magnetic_total_magnetization(mesh, st, qq, trans_mag)
subroutine, public compute_and_write_magnetic_moments(gr, st, phase, ep, ions, lmm_r, calc_orb_moments, iunit, namespace)
Computes and prints the global and local magnetic moments.
subroutine, public write_total_xc_torque(iunit, mesh, vxc, st)
subroutine, public magnetic_density(mesh, std, rho, md)
subroutine, public magnetic_induced(namespace, gr, st, psolver, kpoints, a_ind, b_ind)
This subroutine receives as input a current, and produces as an output the vector potential that it i...
This module is intended to contain "only mathematical" functions and procedures.
pure real(real64) function, dimension(1:3), public dcross_product(a, b)
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
type(mpi_grp_t), public mpi_world
subroutine, public dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Calculates the Poisson equation. Given the density returns the corresponding potential.
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.
subroutine, public zprojector_commute_r(pj, mesh, bnd, dim, idir, ik, psi, cpsi)
This function calculates |cpsi> += [x, V_nl] |psi>
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_calc_quantities(gr, st, kpoints, nlcc, kinetic_energy_density, paramagnetic_current, density_gradient, density_laplacian, gi_kinetic_energy_density, st_end)
calculated selected quantities
real(real64) function, public dsm_integrate_frommesh(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
This class contains information about the boundary conditions.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.
A container for the phase.
The states_elec_t class contains all electronic wave functions.
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...
batches of electronic states