27 use,
intrinsic :: iso_fortran_env
50 integer :: coupling_mode
51 integer :: coupling_terms
52 integer :: dipole_field
53 real(real64),
allocatable :: e_field(:,:)
54 real(real64),
allocatable :: b_field(:,:)
55 real(real64),
allocatable :: vec_pot(:,:)
56 real(real64),
allocatable :: e_field_dip(:)
57 real(real64),
allocatable :: vec_pot_dip(:)
58 real(real64),
allocatable :: b_field_dip(:)
59 real(real64),
allocatable :: e_quadrupole_pot(:)
60 logical :: calc_field_dip = .false.
61 logical :: add_electric_dip = .false.
62 logical :: add_electric_quad = .false.
63 logical :: add_magnetic_dip = .false.
64 logical :: add_zeeman = .false.
65 logical :: add_non_uniform_vec_pot = .false.
66 real(real64) :: center_of_mass(1:3)
67 integer :: center_of_mass_ip
68 integer :: center_of_mass_rankmin
69 logical :: test_equad = .false.
70 type(derivatives_t),
pointer,
private :: der
71 real(real64),
private :: mass
75 integer,
public,
parameter :: &
76 NO_MAXWELL_COUPLING = 0, &
82 integer,
public,
parameter :: &
92 type(mxll_coupling_t),
intent(inout) :: this
93 type(states_elec_dim_t),
intent(in) :: d
94 type(grid_t),
target,
intent(in) :: gr
95 type(namespace_t),
intent(in) :: namespace
96 real(real64),
intent(in) :: mass
98 integer :: terms_default, fmc_default, multipolar_terms, pauli_terms
130 call parse_variable(namespace,
'MaxwellCouplingMode', no_maxwell_coupling, &
155 option__multipolarexpansionterms__electric_dipole + &
156 option__multipolarexpansionterms__electric_quadrupole + &
157 option__multipolarexpansionterms__magnetic_dipole
159 call parse_variable(namespace,
'MultipolarExpansionTerms', terms_default, multipolar_terms)
161 if (
bitand(multipolar_terms, option__multipolarexpansionterms__electric_dipole) /= 0)
then
164 if (
bitand(multipolar_terms, option__multipolarexpansionterms__electric_quadrupole) /=0)
then
165 this%add_electric_quad = .
true.
167 if (
bitand(multipolar_terms, option__multipolarexpansionterms__magnetic_dipole) /=0)
then
187 if (d%nspin == 2)
then
188 fmc_default = option__paulihamiltonianterms__non_uniform_vector_potential + &
189 option__paulihamiltonianterms__zeeman_term
191 fmc_default = option__paulihamiltonianterms__non_uniform_vector_potential
194 call parse_variable(namespace,
'PauliHamiltonianTerms', fmc_default, pauli_terms)
195 if (
bitand(pauli_terms, option__paulihamiltonianterms__non_uniform_vector_potential) /= 0)
then
196 this%add_non_uniform_vec_pot = .
true.
198 if (
bitand(pauli_terms, option__paulihamiltonianterms__zeeman_term) /=0)
then
199 this%add_zeeman = .
true.
216 call parse_variable(namespace,
'MaxwellDipoleField', dipole_average, &
219 if (this%coupling_mode /= no_maxwell_coupling)
then
220 safe_allocate(this%e_field(1:gr%np, 1:gr%box%dim))
221 safe_allocate(this%b_field(1:gr%np, 1:gr%box%dim))
222 safe_allocate(this%vec_pot(1:gr%np, 1:gr%box%dim))
226 safe_allocate(this%e_field_dip(1:gr%box%dim))
228 safe_allocate(this%b_field_dip(1:gr%box%dim))
230 safe_allocate(this%vec_pot_dip(1:gr%box%dim))
235 safe_allocate(this%e_quadrupole_pot(1:gr%np))
250 type(
grid_t),
intent(in) :: gr
253 integer :: ip, rankmin
265 call parse_variable(namespace,
'MaxwellTestQuadrupole', .false., this%test_equad)
267 if (this%test_equad)
then
268 safe_allocate(this%e_field(1:gr%np, 1:gr%box%dim))
271 this%e_field(ip,1) = 0.02_real64 * gr%x(ip,1)
273 this%calc_field_dip = .
true.
274 this%center_of_mass(1:3) =
m_zero
276 this%center_of_mass_rankmin = rankmin
277 safe_allocate(this%e_quadrupole_pot(1:gr%np))
289 type(
mesh_t),
intent(in) :: mesh
291 class(
space_t),
intent(in) :: space
293 integer :: ip, ispin, idir
298 select case (this%coupling_mode)
302 if (this%add_electric_dip)
then
303 do ispin = 1, d%spin_channels
306 hm_base%potential(ip, ispin) = hm_base%potential(ip, ispin) + &
307 sum(this%e_field_dip(1:space%dim) * (mesh%x(ip, 1:space%dim) - this%center_of_mass(1:space%dim)))
312 if (this%add_electric_quad .and. this%calc_field_dip)
then
315 do ispin = 1, d%spin_channels
317 hm_base%potential(ip, ispin) = hm_base%potential(ip, ispin) + this%e_quadrupole_pot(ip)
327 hm_base%uniform_vector_potential(1:space%dim) = hm_base%uniform_vector_potential(1:space%dim) - &
328 this%vec_pot_dip(1:space%dim)
332 if (this%add_non_uniform_vec_pot)
then
333 do idir = 1, mesh%box%dim
334 hm_base%vector_potential(idir, :) = hm_base%vector_potential(idir, :) + this%vec_pot(:, idir)
337 if (this%add_zeeman)
then
339 hm_base%magnetic_field(:,:) = hm_base%magnetic_field(:,:) + this%b_field(:,:)
355 safe_deallocate_a(this%e_field)
356 safe_deallocate_a(this%b_field)
357 safe_deallocate_a(this%vec_pot)
358 safe_deallocate_a(this%e_field_dip)
359 safe_deallocate_a(this%b_field_dip)
360 safe_deallocate_a(this%vec_pot_dip)
361 safe_deallocate_a(this%e_quadrupole_pot)
373 type(
mesh_t),
intent(in) :: mesh
375 real(real64),
allocatable :: e_field_quadrupole_tensor(:,:), tmp_partial(:,:), this_e_field(:,:)
376 real(real64) :: r(3), tensor_dot_rr(3)
377 integer :: ip, i, dims
383 safe_allocate(e_field_quadrupole_tensor(1:mesh%box%dim, 1:mesh%box%dim))
384 safe_allocate(this_e_field(1:mesh%np_part, 1:mesh%box%dim))
385 safe_allocate(tmp_partial(1:mesh%np, 1:mesh%box%dim))
387 this_e_field(1:mesh%np,:) = this%e_field(1:mesh%np,:)
389 e_field_quadrupole_tensor =
m_zero
393 if (mesh%mpi_grp%rank == this%center_of_mass_rankmin)
then
394 e_field_quadrupole_tensor(i, 1:dims) = tmp_partial(this%center_of_mass_ip, 1:dims)
397 if (mesh%parallel_in_domains)
call mesh%allreduce(e_field_quadrupole_tensor)
400 r(:) = mesh%x(ip,:) - this%center_of_mass(:)
401 tensor_dot_rr = matmul(e_field_quadrupole_tensor, r)
403 this%e_quadrupole_pot(ip) =
m_half * dot_product(r, tensor_dot_rr)
406 safe_deallocate_a(e_field_quadrupole_tensor)
407 safe_deallocate_a(tmp_partial)
408 safe_deallocate_a(this_e_field)
427 real(real64) :: rtmp(3)
428 real(real64),
allocatable :: bxr(:,:)
434 safe_allocate(bxr(1:this%der%mesh%np,1:3))
437 do ip = 1, this%der%mesh%np
438 rtmp(:) = this%der%mesh%x(ip,:) - this%center_of_mass
444 call hpsib%copy_to(bxr_dot_gradb)
445 do idir = 1, this%der%dim
446 call batch_mul(this%der%mesh%np, bxr(:,idir), gradb(idir), bxr_dot_gradb)
450 call bxr_dot_gradb%end()
451 do idir = 1, this%der%dim
452 call gradb(idir)%end()
454 safe_deallocate_a(bxr)
batchified version of the BLAS axpy routine:
This module implements common operations on batches of mesh functions.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
subroutine, public zderivatives_batch_grad(der, ffb, opffb, ghost_update, set_bc, to_cartesian, metric, factor)
apply the gradient to a batch of mesh functions
real(real64), parameter, public m_zero
complex(real64), parameter, public m_zi
real(real64), parameter, public m_half
This module implements the underlying real-space grid.
integer, parameter, public field_uniform_vector_potential
integer, parameter, public field_vector_potential
integer, parameter, public field_magnetic_field
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 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.
subroutine, public mxll_coupling_init(this, d, gr, namespace, mass)
Parse variables and initialize Maxwell coupling.
subroutine, public set_electric_quadrupole_pot(this, mesh)
Computes the electric quadrupole potential where .
subroutine mxll_quadrupole_test_init(this, gr, namespace)
Initializes quadrupole test when requested. The test applies an electric field defined as E=(0....
integer, parameter, public length_gauge_dipole
subroutine, public mxll_coupling_end(this)
Finalize and deallocate Maxwell coupling arrays.
subroutine, public mxll_coupling_calc(this, hm_base, mesh, d, space)
Add the Maxwell coupling to the electronic Hamiltonian.
integer, parameter, public velocity_gauge_dipole
integer, parameter, public multipolar_expansion
subroutine, public magnetic_dipole_coupling(this, psib, hpsib)
Computes the magnetic dipole term of the Hamiltonian. This routine acually implements the equivalent...
integer, parameter, public dipole_at_com
integer, parameter, public full_minimal_coupling
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.
This module handles spin dimensions of the states and the k-point distribution.
Description of the grid, containing information on derivatives, stencil, and symmetries.
The basic Hamiltonian for electronic system.
Describes mesh distribution to nodes.
class for organizing spins and k-points
batches of electronic states