28 use,
intrinsic :: iso_fortran_env
65 integer,
public,
parameter :: &
66 KICK_FUNCTION_DIPOLE = 0, &
70 integer,
public,
parameter :: &
71 KICK_DENSITY_MODE = 0, &
76 integer,
public,
parameter :: &
92 integer,
private :: delta_strength_mode
93 real(real64) :: delta_strength
95 real(real64),
allocatable :: pol(:,:)
97 integer :: pol_equiv_axes
98 real(real64),
allocatable :: wprime(:)
99 real(real64) :: easy_axis(3)
111 integer :: n_multipoles
112 integer,
allocatable :: l(:), m(:)
113 real(real64),
allocatable :: weight(:)
116 real(real64),
allocatable :: qvector(:,:)
117 real(real64) :: trans_vec(3, 2)
118 real(real64) :: qlength
119 integer :: qkick_mode
120 integer :: qbessel_l, qbessel_m
122 integer :: function_mode
123 character(len=200),
private:: user_defined_function
129 subroutine kick_init(kick, namespace, space, kpoints, nspin)
130 type(kick_t),
intent(inout) :: kick
131 type(namespace_t),
intent(in) :: namespace
132 class(space_t),
intent(in) :: space
133 type(kpoints_t),
intent(in) :: kpoints
134 integer,
intent(in) :: nspin
137 integer :: n_rows, irow, idir, iop, iq, iqx, iqy, iqz
138 real(real64) :: norm, dot
139 real(real64) :: qtemp(space%dim)
140 integer :: periodic_dim
145 periodic_dim = space%periodic_dim
148 safe_allocate(kick%pol(1:space%dim, 1:space%dim))
149 safe_allocate(kick%wprime(1:space%dim))
163 if (kick%time >
m_zero)
then
183 kick%function_mode = kick_function_dipole
186 kick%delta_strength_mode = 0
187 kick%pol_equiv_axes = 0
191 kick%n_multipoles = 0
192 kick%qkick_mode = qkickmode_none
226 call parse_variable(namespace,
'TDDeltaStrengthMode', kick_density_mode, kick%delta_strength_mode)
227 select case (kick%delta_strength_mode)
228 case (kick_density_mode)
232 call messages_input_error(namespace,
'TDDeltaStrengthMode',
'Magnon kick is incompatible with spinors')
241 kick%n_multipoles = 0
253 call parse_variable(namespace,
'TDDeltaUserDefined',
'0', kick%user_defined_function)
270 else if (
parse_block(namespace,
'TDKickFunction', blk) == 0)
then
274 kick%n_multipoles = n_rows
275 safe_allocate( kick%l(1:n_rows))
276 safe_allocate( kick%m(1:n_rows))
277 safe_allocate(kick%weight(1:n_rows))
282 if ((kick%l(irow) < 0) .or. (abs(kick%m(irow)) > abs(kick%l(irow))))
then
289 kick%function_mode = kick_function_dipole
290 kick%n_multipoles = 0
302 call parse_variable(namespace,
'TDPolarizationEquivAxes', 0, kick%pol_equiv_axes)
319 call parse_variable(namespace,
'TDPolarizationDirection', 0, kick%pol_dir)
322 if (kick%pol_dir < 1 .or. kick%pol_dir > kick%dim)
call messages_input_error(namespace,
'TDPolarizationDirection')
364 if (
parse_block(namespace,
'TDPolarization', blk) == 0)
then
367 if (n_rows /= kick%dim)
then
368 call messages_input_error(namespace,
'TDPolarization',
'There should be exactly one line per dimension')
372 do idir = 1, kick%dim
380 do idir = 1, kick%dim
381 if (norm2(kick%pol(1:kick%dim, idir)) <
m_epsilon)
then
384 kick%pol(1:kick%dim, idir) = kick%pol(1:kick%dim, idir) / norm2(kick%pol(1:kick%dim, idir))
388 if (any(abs(kick%pol(1:periodic_dim, :)) >
m_epsilon))
then
389 message(1) =
"Kick cannot be applied in a periodic direction. Use GaugeVectorField instead."
409 if (
parse_block(namespace,
'TDPolarizationWprime', blk) == 0)
then
410 do idir = 1, kick%dim
413 kick%wprime(1:kick%dim) = kick%wprime(1:kick%dim) / norm2(kick%wprime(1:kick%dim))
416 kick%wprime(1:kick%dim-1) =
m_zero
417 kick%wprime(kick%dim) =
m_one
422 if (periodic_dim > 0 .and. kick%delta_strength_mode /=
kick_magnon_mode)
then
423 message(1) =
"Kicks cannot be applied correctly in periodic directions."
435 if (periodic_dim > 0 .and. kick%delta_strength_mode ==
kick_magnon_mode .and. &
436 parse_block(namespace,
'TDReducedMomentumTransfer', blk) == 0)
then
439 safe_allocate(kick%qvector(1:kick%dim, 1))
440 do idir = 1, kick%dim
448 if (kpoints%use_symmetries)
then
452 message(1) =
"The TDMomentumTransfer breaks (at least) one of the symmetries used to reduce the k-points."
453 message(2) =
"Set SymmetryBreakDir equal to TDMomemtumTransfer."
481 else if (
parse_block(namespace,
'TDMomentumTransfer', blk) == 0)
then
483 safe_allocate(kick%qvector(1:kick%dim, 1))
484 do idir = 1, kick%dim
508 if (kpoints%use_symmetries)
then
512 message(1) =
"The TDMomentumTransfer breaks (at least) one of the symmetries used to reduce the k-points."
513 message(2) =
"Set SymmetryBreakDir equal to TDMomemtumTransfer."
520 kick%qkick_mode = qkickmode_none
522 safe_allocate(kick%qvector(1:kick%dim,1))
523 kick%qvector(:,1) =
m_zero
526 kick%qlength = norm2(kick%qvector(:,1))
537 if (
parse_block(namespace,
'TDEasyAxis', blk) == 0)
then
543 norm = norm2(kick%easy_axis(1:3))
544 if (norm < 1e-9_real64)
then
545 message(1) =
"TDEasyAxis norm is too small."
548 kick%easy_axis(1:3) = kick%easy_axis(1:3)/norm
551 message(1) =
"For magnons, the variable TDEasyAxis must be defined."
558 kick%trans_vec(1,1) = -kick%easy_axis(2)
559 kick%trans_vec(2,1) =
m_two*kick%easy_axis(3)
560 kick%trans_vec(3,1) =
m_three*kick%easy_axis(1)
562 dot = sum(kick%easy_axis(1:3)*kick%trans_vec(1:3,1))
563 kick%trans_vec(1:3,1) = kick%trans_vec(1:3,1) - dot*kick%easy_axis(1:3)
564 norm = sum(kick%trans_vec(1:3,1)**2)
565 kick%trans_vec(1:3,1) = kick%trans_vec(1:3,1)/
sqrt(norm)
568 kick%trans_vec(1,2) = kick%easy_axis(2) * kick%trans_vec(3,1) - kick%easy_axis(3) * kick%trans_vec(2,1)
569 kick%trans_vec(2,2) = kick%easy_axis(3) * kick%trans_vec(1,1) - kick%easy_axis(1) * kick%trans_vec(3,1)
570 kick%trans_vec(3,2) = kick%easy_axis(1) * kick%trans_vec(2,1) - kick%easy_axis(2) * kick%trans_vec(1,1)
578 message(1) =
"TDMomentumTransfer and TDMultipleMomentumTransfer cannot be defined at the same time."
604 if (
parse_block(namespace,
'TDMultipleMomentumTransfer', blk) /= 0)
then
605 write(
message(1),
'(a)')
'Internal error while reading TDMultipleMomentumTransfer.'
616 kick%nqvec = (2*kick%nqmult(1)+1)*(2*kick%nqmult(2)+1)*(2*kick%nqmult(3)+1)
618 safe_deallocate_a(kick%qvector)
619 safe_allocate(kick%qvector(1:3, 1:kick%nqvec))
621 do iqx = -kick%nqmult(1), kick%nqmult(1)
622 do iqy = -kick%nqmult(2), kick%nqmult(2)
623 do iqz = -kick%nqmult(3), kick%nqmult(3)
625 qtemp(1:3) = (/iqx, iqy, iqz/)
629 if (kpoints%use_symmetries)
then
633 message(1) =
"The TDMultipleMomentumTransfer breaks (at least) one " &
634 //
"of the symmetries used to reduce the k-points."
635 message(2) =
"Set SymmetryBreakDir accordingly."
647 kick%easy_axis(:) =
m_zero
651 message(1) =
"For magnons, the kick mode must be exponential."
661 type(
kick_t),
intent(inout) :: kick_out
662 type(
kick_t),
intent(in) :: kick_in
666 kick_out%dim = kick_in%dim
668 kick_out%time = kick_in%time
670 kick_out%delta_strength_mode = kick_in%delta_strength_mode
671 kick_out%delta_strength = kick_in%delta_strength
674 safe_allocate_source_a(kick_out%pol, kick_in%pol)
675 kick_out%pol_dir = kick_in%pol_dir
676 kick_out%pol_equiv_axes = kick_in%pol_equiv_axes
677 safe_allocate_source_a(kick_out%wprime, kick_in%wprime)
680 kick_out%n_multipoles = kick_in%n_multipoles
681 if (kick_out%n_multipoles > 0)
then
682 safe_allocate_source_a(kick_out%l, kick_in%l)
683 safe_allocate_source_a(kick_out%m, kick_in%m)
684 safe_allocate_source_a(kick_out%weight, kick_in%weight)
686 kick_out%nqvec = kick_in%nqvec
687 safe_allocate_source_a(kick_out%qvector, kick_in%qvector)
688 kick_out%qlength = kick_in%qlength
689 kick_out%qkick_mode = kick_in%qkick_mode
690 kick_out%qbessel_l = kick_in%qbessel_l
691 kick_out%qbessel_m = kick_in%qbessel_m
694 kick_out%function_mode = kick_in%function_mode
695 kick_out%user_defined_function = kick_in%user_defined_function
697 kick_out%easy_axis = kick_in%easy_axis
704 type(
kick_t),
intent(inout) :: kick
708 kick%delta_strength_mode = 0
710 kick%pol_equiv_axes = 0
711 safe_deallocate_a(kick%pol)
713 safe_deallocate_a(kick%wprime)
714 if (kick%n_multipoles > 0)
then
715 safe_deallocate_a(kick%l)
716 safe_deallocate_a(kick%m)
717 safe_deallocate_a(kick%weight)
719 kick%n_multipoles = 0
720 kick%qkick_mode = qkickmode_none
721 safe_deallocate_a(kick%qvector)
727 subroutine kick_read(kick, iunit, namespace)
728 type(
kick_t),
intent(inout) :: kick
729 integer,
intent(in) :: iunit
732 integer :: idir, im, ierr
733 character(len=100) :: line
737 kick%function_mode = -1
739 read(iunit,
'(15x,i2)') kick%delta_strength_mode
740 read(iunit,
'(15x,f18.12)') kick%delta_strength
741 read(iunit,
'(15x,i2)') kick%dim
742 read(iunit,
'(a)') line
743 if (index(line,
'defined') /= 0)
then
746 read(line,
'(16x,a)') kick%user_defined_function
747 elseif (index(line,
'multipole') /= 0)
then
750 read(line,
'(15x,i3)') kick%n_multipoles
751 safe_allocate( kick%l(1:kick%n_multipoles))
752 safe_allocate( kick%m(1:kick%n_multipoles))
753 safe_allocate(kick%weight(1:kick%n_multipoles))
754 do im = 1, kick%n_multipoles
756 read(iunit,
'(15x,2i3,f18.12)') kick%l(im), kick%m(im), kick%weight(im)
759 kick%function_mode = kick_function_dipole
760 kick%n_multipoles = 0
763 safe_allocate(kick%pol(1:kick%dim, 1:kick%dim))
764 safe_allocate(kick%wprime(1:kick%dim))
765 do idir = 1, kick%dim
766 read(iunit,
'(15x,99f18.12)') kick%pol(1:kick%dim, idir)
768 read(iunit,
'(15x,i2)') kick%pol_dir
769 read(iunit,
'(15x,i2)') kick%pol_equiv_axes
770 read(iunit,
'(15x,99f18.12)') kick%wprime(1:kick%dim)
773 read(iunit,
'(15x,i3)') kick%nqvec
774 safe_allocate(kick%qvector(1:3, 1:kick%nqvec))
775 do im = 1, kick%nqvec
776 read(iunit,
'(15x,3f18.12)') kick%qvector(1:kick%dim, im)
778 read(iunit,
'(15x,3f18.12)') kick%easy_axis(1:3)
779 read(iunit,
'(15x,3f18.12)') kick%trans_vec(1:3,1)
780 read(iunit,
'(15x,3f18.12)') kick%trans_vec(1:3,2)
782 read(iunit,
'(15x,f18.12)', iostat = ierr) kick%time
789 if (kick%function_mode < 0)
then
790 message(1) =
"No kick could be read from file."
800 type(
kick_t),
intent(in) :: kick
801 integer,
optional,
intent(in) :: iunit
802 type(c_ptr),
optional,
intent(inout) :: out
805 character(len=120) :: aux
809 if (
present(iunit))
then
810 write(iunit,
'(a15,i1)')
'# kick mode ', kick%delta_strength_mode
811 write(iunit,
'(a15,f18.12)')
'# kick strength', kick%delta_strength
812 write(iunit,
'(a15,i2)')
'# dim ', kick%dim
815 write(iunit,
'(a15,1x,a)')
'# User defined:', trim(kick%user_defined_function)
816 elseif (kick%n_multipoles > 0)
then
817 write(iunit,
'(a15,i3)')
'# N multipoles ', kick%n_multipoles
818 do im = 1, kick%n_multipoles
819 write(iunit,
'(a15,2i3,f18.12)')
'# multipole ', kick%l(im), kick%m(im), kick%weight(im)
822 do idir = 1, kick%dim
823 write(iunit,
'(a6,i1,a8,99f18.12)')
'# pol(', idir,
') ', kick%pol(1:kick%dim, idir)
825 write(iunit,
'(a15,i1)')
'# direction ', kick%pol_dir
826 write(iunit,
'(a15,i1)')
'# Equiv. axes ', kick%pol_equiv_axes
827 write(iunit,
'(a15,99f18.12)')
'# wprime ', kick%wprime(1:kick%dim)
829 write(iunit,
'(a15,f18.12)')
"# kick time ", kick%time
831 else if (
present(out))
then
832 write(aux,
'(a15,i2)')
'# kick mode ', kick%delta_strength_mode
835 write(aux,
'(a15,f18.12)')
'# kick strength', kick%delta_strength
838 write(aux,
'(a15,i2)')
'# dim ', kick%dim
842 write(aux,
'(a15,1x,a)')
'# User defined:', trim(kick%user_defined_function)
845 elseif (kick%n_multipoles > 0)
then
846 write(aux,
'(a15,i3)')
'# N multipoles ', kick%n_multipoles
849 do im = 1, kick%n_multipoles
850 write(aux,
'(a15,2i3,f18.12)')
'# multipole ', kick%l(im), kick%m(im), kick%weight(im)
855 do idir = 1, kick%dim
856 write(aux,
'(a6,i1,a8,99f18.12)')
'# pol(', idir,
') ', kick%pol(1:kick%dim, idir)
860 write(aux,
'(a15,i2)')
'# direction ', kick%pol_dir
863 write(aux,
'(a15,i2)')
'# Equiv. axes ', kick%pol_equiv_axes
866 write(aux,
'(a15,99f18.12)')
'# wprime ', kick%wprime(1:kick%dim)
871 write(aux,
'(a15,i3)')
'# N q-vectors ', kick%nqvec
874 do im = 1, kick%nqvec
875 write(aux,
'(a15,3f18.12)')
'# q-vector ', kick%qvector(1:kick%dim, im)
879 write(aux,
'(a15,3f18.12)')
'# Easy axis ', kick%easy_axis(1:3)
882 write(aux,
'(a15,3f18.12)')
'# Trans. dir 1 ', kick%trans_vec(1:3,1)
885 write(aux,
'(a15,3f18.12)')
'# Trans. dir 2 ', kick%trans_vec(1:3,2)
889 write(aux,
'(a15,f18.12)')
"# kick time ", kick%time
901 subroutine kick_function_get(space, mesh, kick, kick_function, iq, to_interpolate)
902 class(
space_t),
intent(in) :: space
903 class(
mesh_t),
intent(in) :: mesh
904 type(
kick_t),
intent(in) :: kick
905 complex(real64),
contiguous,
intent(out) :: kick_function(:)
906 integer,
intent(in) :: iq
907 logical,
optional,
intent(in) :: to_interpolate
910 real(real64) :: xx(space%dim)
911 real(real64) :: rkick, ikick, rr, ylm
918 if (
present(to_interpolate))
then
919 if (to_interpolate) np = mesh%np_part
924 select case (kick%qkick_mode)
926 write(
message(1),
'(a,3F9.5,a)')
'Info: Using cos(q.r) field with q = (', kick%qvector(1:3, iq),
')'
928 write(
message(1),
'(a,3F9.5,a)')
'Info: Using sin(q.r) field with q = (', kick%qvector(1:3, iq),
')'
930 write(
message(1),
'(a,3F9.5,a)')
'Info: Using sin(q.r)+cos(q.r) field with q = (', kick%qvector(1:3, iq),
')'
932 select case(kick%dim)
934 write(
message(1),
'(a,1F9.5,a)')
'Info: Using exp(iq.r) field with q = (', kick%qvector(1:kick%dim, iq),
')'
936 write(
message(1),
'(a,2F9.5,a)')
'Info: Using exp(iq.r) field with q = (', kick%qvector(1:kick%dim, iq),
')'
938 write(
message(1),
'(a,3F9.5,a)')
'Info: Using exp(iq.r) field with q = (', kick%qvector(1:kick%dim, iq),
')'
941 write(
message(1),
'(a,I2,a,I2,a,F9.5)')
'Info: Using j_l(qr)*Y_lm(r) field with (l,m)= (', &
942 kick%qbessel_l,
",", kick%qbessel_m,
') and q = ', kick%qlength
944 write(
message(1),
'(a)')
'Info: Unknown field type!'
951 select case (kick%qkick_mode)
953 kick_function(ip) = kick_function(ip) +
cos(dot_product(kick%qvector(1:kick%dim, iq), xx))
955 kick_function(ip) = kick_function(ip) +
sin(dot_product(kick%qvector(1:kick%dim, iq), xx))
957 kick_function(ip) = kick_function(ip) +
sin(dot_product(kick%qvector(1:kick%dim, iq), xx))
959 kick_function(ip) = kick_function(ip) +
exp(
m_zi * dot_product(kick%qvector(:, iq), xx))
961 call ylmr_real(xx, kick%qbessel_l, kick%qbessel_m, ylm)
962 kick_function(ip) = kick_function(ip) +
loct_sph_bessel(kick%qbessel_l, kick%qlength*norm2(xx))*ylm
971 call mesh_r(mesh, ip, rr, coords = xx)
975 kick_function(ip) = rkick
978 elseif (kick%n_multipoles > 0)
then
981 do im = 1, kick%n_multipoles
983 call mesh_r(mesh, ip, rr, coords = xx)
984 call loct_ylm(1, xx(1), xx(2), xx(3), kick%l(im), kick%m(im), ylm)
985 kick_function(ip) = kick_function(ip) + kick%weight(im) * (rr**kick%l(im)) * ylm
990 kick_function(ip) = sum(mesh%x(1:space%dim, ip) * &
991 kick%pol(1:space%dim, kick%pol_dir))
1003 class(
space_t),
intent(in) :: space
1004 class(
mesh_t),
intent(in) :: mesh
1005 type(
kick_t),
intent(in) :: kick
1007 type(
pcm_t),
intent(inout) :: pcm
1008 complex(real64),
contiguous,
intent(out) :: kick_pcm_function(:)
1010 complex(real64),
allocatable :: kick_function_interpolate(:)
1011 real(real64),
allocatable :: kick_function_real(:)
1015 kick_pcm_function =
m_zero
1016 if (pcm%localf)
then
1017 safe_allocate(kick_function_interpolate(1:mesh%np_part))
1018 kick_function_interpolate =
m_zero
1020 safe_allocate(kick_function_real(1:mesh%np_part))
1021 kick_function_real =real(kick_function_interpolate, real64)
1022 if (pcm%kick_like)
then
1024 call pcm_calc_pot_rs(pcm, mesh, psolver, kick = kick%delta_strength * kick_function_real, kick_time = .
true.)
1025 else if (.not. pcm%kick_like .and. pcm%which_eps ==
pcm_debye_model)
then
1027 pcm%kick_like = .
true.
1028 call pcm_calc_pot_rs(pcm, mesh, psolver, kick = kick%delta_strength * kick_function_real, kick_time = .
true.)
1029 pcm%kick_like = .false.
1030 else if (.not. pcm%kick_like .and. pcm%which_eps ==
pcm_drude_model)
then
1034 kick_pcm_function = pcm%v_kick_rs / kick%delta_strength
1044 subroutine kick_apply(space, mesh, st, ions_dyn, ions, kick, psolver, kpoints, pcm)
1045 class(
space_t),
intent(in) :: space
1046 class(
mesh_t),
intent(in) :: mesh
1049 type(
ions_t),
intent(inout) :: ions
1050 type(
kick_t),
intent(in) :: kick
1053 type(
pcm_t),
optional,
intent(inout) :: pcm
1055 integer :: iqn, ist, idim, ip, ispin, iatom
1056 complex(real64) :: cc(2), kick_value
1057 complex(real64),
allocatable :: kick_function(:), psi(:, :)
1059 complex(real64),
allocatable :: kick_pcm_function(:)
1061 real(real64) :: uvec(3), vvec(3), gvec(3, 3)
1062 real(real64) :: xx(space%dim), rr
1063 complex(real64) :: cross_term
1064 real(real64) :: cross_factor
1070 delta_strength:
if (abs(kick%delta_strength) >
m_epsilon)
then
1072 safe_allocate(kick_function(1:mesh%np))
1073 if (kick%delta_strength_mode /=
kick_magnon_mode .or. kick%nqvec == 1)
then
1078 if (
present(pcm))
then
1079 safe_allocate(kick_pcm_function(1:mesh%np))
1081 kick_function = kick_function + kick_pcm_function
1084 write(
message(1),
'(a,f11.6)')
'Info: Applying delta kick: k = ', kick%delta_strength
1085 select case (kick%function_mode)
1086 case (kick_function_dipole)
1087 message(2) =
"Info: kick function: dipole."
1089 message(2) =
"Info: kick function: multipoles."
1091 message(2) =
"Info: kick function: user defined function."
1093 select case (kick%delta_strength_mode)
1094 case (kick_density_mode)
1095 message(3) =
"Info: Delta kick mode: Density mode"
1099 message(3) =
"Info: Delta kick mode: Density + Spin modes"
1104 if (st%d%nspin == 2) ns = 2
1106 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
1110 do iqn = st%d%kpt%start, st%d%kpt%end
1111 do ist = st%st_start, st%st_end
1114 select case (kick%delta_strength_mode)
1115 case (kick_density_mode)
1116 do idim = 1, st%d%dim
1118 psi(ip, idim) =
exp(
m_zi*kick%delta_strength*kick_function(ip))*psi(ip, idim)
1123 ispin = st%d%get_spin_index(iqn)
1125 kick_value =
m_zi*kick%delta_strength*kick_function(ip)
1127 cc(1) =
exp(kick_value)
1128 cc(2) =
exp(-kick_value)
1130 select case (st%d%ispin)
1132 psi(ip, 1) = cc(ispin)*psi(ip, 1)
1134 psi(ip, 1) = cc(1)*psi(ip, 1)
1135 psi(ip, 2) = cc(2)*psi(ip, 2)
1141 kick_value =
m_zi*kick%delta_strength*kick_function(ip)
1144 select case (st%d%ispin)
1147 psi(ip, 1) = cc(1)*psi(ip, 1)
1150 psi(ip, 1) = cc(1)*psi(ip, 1)
1163 if (kick%nqvec == 1)
then
1166 uvec(1:3) = kick%trans_vec(1:3,1)
1167 vvec(1:3) = kick%trans_vec(1:3,2)
1169 do iqn = st%d%kpt%start, st%d%kpt%end, ns
1170 do ist = st%st_start, st%st_end
1180 psi(ip, 1) =
cos(kick%delta_strength)* cc(1)
1181 psi(ip, 2) =
cos(kick%delta_strength)* cc(2)
1187 psi(ip, 1) = psi(ip, 1) -
m_zi*
sin(kick%delta_strength)*( real(kick_function(ip), real64) &
1188 * (uvec(3)*cc(1) + cmplx(uvec(1),-uvec(2), real64)*cc(2)) &
1189 + aimag(kick_function(ip)) * (vvec(3)*cc(1) + cmplx(vvec(1),-vvec(2), real64)*cc(2)))
1190 psi(ip, 2) = psi(ip, 2) -
m_zi*
sin(kick%delta_strength)*( real(kick_function(ip), real64) &
1191 * (-uvec(3)*cc(2) + cmplx(uvec(1),uvec(2), real64)*cc(1)) &
1192 + aimag(kick_function(ip)) * (-vvec(3)*cc(2) + cmplx(vvec(1),vvec(2), real64)*cc(1)))
1207 kick_function =
m_one
1209 call mesh_r(mesh, ip, rr, coords = xx)
1211 if (kick%nqmult(iq) == 0) cycle
1214 kick_function(ip) = kick_function(ip)*
sin(
m_half*(2*kick%nqmult(iq)+1) &
1215 *sum(gvec(1:3, iq) * xx(1:3)))/
sin(
m_half*sum(gvec(1:3, iq) * xx(1:3)))
1217 kick_function(ip) = kick_function(ip)*kick%delta_strength
1222 if (kick%easy_axis(3) >=
m_zero)
then
1223 cross_factor =
m_one / (
m_one + kick%easy_axis(3))
1224 else if (kick%easy_axis(1)**2 + kick%easy_axis(2)**2 >
m_epsilon**2)
then
1225 cross_factor = (
m_one - kick%easy_axis(3)) / (kick%easy_axis(1)**2 + kick%easy_axis(2)**2)
1229 cross_term = kick%easy_axis(2)*cmplx(kick%easy_axis(1),-kick%easy_axis(2), real64) * cross_factor &
1230 -
m_zi * kick%easy_axis(3)
1232 do iqn = st%d%kpt%start, st%d%kpt%end, ns
1233 do ist = st%st_start, st%st_end
1246 psi(ip, 1) = (
cos(kick_function(ip)) +
m_zi * kick%easy_axis(1)*
sin(kick_function(ip)))*cc(1) &
1247 +
sin(kick_function(ip)) * cross_term * cc(2)
1248 psi(ip, 2) = -
sin(kick_function(ip)) * conjg(cross_term) * cc(1) &
1249 + (
cos(kick_function(ip)) -
m_zi * kick%easy_axis(1)*
sin(kick_function(ip)))*cc(2)
1260 safe_deallocate_a(psi)
1265 if (ions_dyn%ions_move() .and. abs(kick%delta_strength) >
m_epsilon)
then
1267 do iatom = 1, ions%natoms
1268 ions%vel(:, iatom) = ions%vel(:, iatom) + &
1269 kick%delta_strength * kick%pol(1:ions%space%dim, kick%pol_dir) * &
1275 safe_deallocate_a(kick_function)
1276 end if delta_strength
1282 type(
kick_t),
intent(in) :: kick
1284 kick_type = kick%delta_strength_mode
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
integer, parameter, public spinors
integer, parameter, public spin_polarized
real(real64), parameter, public m_two
real(real64), parameter, public p_proton_charge
real(real64), parameter, public m_zero
complex(real64), parameter, public m_z0
complex(real64), parameter, public m_zi
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_one
real(real64), parameter, public m_three
subroutine, public kick_copy(kick_out, kick_in)
integer, parameter, public kick_magnon_mode
integer, parameter, public kick_function_multipole
subroutine, public kick_read(kick, iunit, namespace)
subroutine kick_pcm_function_get(space, mesh, kick, psolver, pcm, kick_pcm_function)
integer, parameter, public kick_spin_mode
integer, parameter, public qkickmode_exp
integer, parameter, public qkickmode_cos
subroutine, public kick_end(kick)
integer, parameter, public qkickmode_sin
subroutine, public kick_init(kick, namespace, space, kpoints, nspin)
subroutine, public kick_function_get(space, mesh, kick, kick_function, iq, to_interpolate)
pure integer function, public kick_get_type(kick)
subroutine, public kick_apply(space, mesh, st, ions_dyn, ions, kick, psolver, kpoints, pcm)
Applies the delta-function electric field where k = kick%delta_strength.
subroutine, public kick_write(kick, iunit, out)
integer, parameter, public kick_function_user_defined
integer, parameter, public qkickmode_bessel
integer, parameter, public kick_spin_density_mode
subroutine, public kpoints_to_absolute(latt, kin, kout)
This module is intended to contain "only mathematical" functions and procedures.
subroutine, public ylmr_real(xx, li, mi, ylm)
This is a Numerical Recipes-based subroutine computes real spherical harmonics ylm at position (x,...
This module defines the meshes, which are used in Octopus.
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
subroutine, public messages_warning(no_lines, all_nodes, 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_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
logical function, public parse_is_defined(namespace, name)
integer function, public parse_block(namespace, name, blk, check_varinfo_)
integer, parameter, public pcm_drude_model
integer, parameter, public pcm_debye_model
subroutine, public pcm_calc_pot_rs(pcm, mesh, psolver, ions, v_h, v_ext, kick, time_present, kick_time)
This module handles spin dimensions of the states and the k-point distribution.
logical pure function, public is_spin_up(ik)
Returns true if k-point ik denotes spin-up, in spin-polarized case.
integer pure function, public symmetries_identity_index(this)
integer pure function, public symmetries_number(this)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
Explicit interfaces to C functions, defined in write_iter_low.cc.
subroutine, public write_iter_string(out, string)
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.