53 real(real64),
pointer :: vmf(:)
54 real(real64),
allocatable :: dipole(:)
55 real(real64),
allocatable :: dipole_former(:)
56 complex(real64),
allocatable :: integral(:)
57 real(real64),
allocatable :: pt_q(:), pt_p(:)
58 real(real64),
allocatable :: pt_q_former(:)
59 real(real64) :: time_former
60 real(real64),
pointer :: fmf(:)
61 logical :: has_restart
67 subroutine mf_init(this, gr, st, ions, pt_mode)
68 type(mf_t),
intent(out) :: this
69 type(grid_t),
intent(in) :: gr
70 type(states_elec_t),
intent(in) :: st
71 type(ions_t),
intent(in) :: ions
72 type(photon_mode_t),
intent(in) :: pt_mode
80 safe_allocate(this%vmf(1:gr%np))
81 safe_allocate(this%dipole(1:ions_dim))
82 safe_allocate(this%dipole_former(1:ions_dim))
84 safe_allocate(this%integral(1:pt_mode%nmodes))
85 safe_allocate(this%pt_q(1:pt_mode%nmodes))
86 safe_allocate(this%pt_p(1:pt_mode%nmodes))
87 safe_allocate(this%pt_q_former(1:pt_mode%nmodes))
88 safe_allocate(this%fmf(1:ions_dim))
91 this%has_restart = .false.
94 this%dipole = - ions%dipole() - st%dipole(gr)
96 this%dipole_former =
m_zero
99 if (pt_mode%has_q0_p0)
then
100 this%pt_q(1:pt_mode%nmodes) = pt_mode%pt_coord_q0(1:pt_mode%nmodes)
101 this%pt_p(1:pt_mode%nmodes) = pt_mode%pt_momen_p0(1:pt_mode%nmodes)
110 this%fmf(1:ions_dim) =
m_zero
118 type(mf_t),
intent(inout) :: this
122 safe_deallocate_p(this%vmf)
123 safe_deallocate_a(this%dipole_former)
124 safe_deallocate_a(this%dipole)
126 safe_deallocate_a(this%integral)
127 safe_deallocate_a(this%pt_p)
128 safe_deallocate_a(this%pt_q)
129 safe_deallocate_a(this%pt_q_former)
131 safe_deallocate_p(this%fmf)
138 subroutine mf_calc(this, gr, st, ions, pt_mode, time)
139 type(mf_t),
intent(inout) :: this
140 type(grid_t),
intent(inout) :: gr
141 type(states_elec_t),
intent(inout) :: st
142 type(ions_t),
intent(in) :: ions
143 type(photon_mode_t),
intent(inout) :: pt_mode
144 real(real64),
intent(in) :: time
146 real(real64) :: lambda_pol_dipole, lambda_pol_dipole_former
147 complex(real64) :: integrand
148 real(real64) :: q0, p0, vmf_coeff
149 integer :: ii, jj, ions_dim
150 logical,
save :: first = .
true.
154 ions_dim = gr%box%dim
156 if (.not. (first .and. this%has_restart))
then
157 do ii = 1, pt_mode%nmodes
158 this%pt_q_former(ii) = this%pt_q(ii)
161 this%dipole_former = this%dipole
162 this%dipole = - ions%dipole() - st%dipole(gr)
166 this%vmf(1:gr%np) =
m_zero
167 this%fmf(1:ions_dim) =
m_zero
169 do ii = 1, pt_mode%nmodes
170 lambda_pol_dipole =
m_zero
171 lambda_pol_dipole_former =
m_zero
173 lambda_pol_dipole = lambda_pol_dipole + &
174 pt_mode%lambda(ii)*pt_mode%pol(ii, jj)*this%dipole(jj)
175 lambda_pol_dipole_former = lambda_pol_dipole_former + &
176 pt_mode%lambda(ii)*pt_mode%pol(ii, jj)*this%dipole_former(jj)
179 if (.not.(first .and. this%has_restart))
then
181 this%integral(ii) =
m_zero
182 else if (abs(this%integral(ii)) <=
m_epsilon)
then
183 this%integral(ii) =
m_half*lambda_pol_dipole*
exp(-
m_zi*pt_mode%omega(ii)*(this%time_former))
185 this%integral(ii) = this%integral(ii) + lambda_pol_dipole*
exp(-
m_zi*pt_mode%omega(ii)*(this%time_former))
189 integrand = -(this%integral(ii)*
exp(
m_zi*pt_mode%omega(ii)*(time)*pt_mode%mu))* &
190 (time*pt_mode%mu - this%time_former)
192 this%pt_q(ii) = aimag(integrand)
193 this%pt_p(ii) = pt_mode%omega(ii)*real(integrand)
195 if (pt_mode%has_q0_p0)
then
196 q0 = pt_mode%pt_coord_q0(ii)*
cos(pt_mode%omega(ii)*(time)*pt_mode%mu)
197 q0 = q0 + pt_mode%pt_momen_p0(ii)/pt_mode%omega(ii)*
sin(pt_mode%omega(ii)*(time)*pt_mode%mu)
198 this%pt_q(ii) = this%pt_q(ii) + q0
200 p0 = -pt_mode%pt_coord_q0(ii)*pt_mode%omega(ii)*
sin(pt_mode%omega(ii)*(time)*pt_mode%mu)
201 p0 = p0 + pt_mode%pt_momen_p0(ii)*
cos(pt_mode%omega(ii)*(time)*pt_mode%mu)
202 this%pt_p(ii) = this%pt_p(ii) + p0
205 if (.not.
allocated(pt_mode%pol_dipole))
then
210 vmf_coeff =
m_half*((lambda_pol_dipole + lambda_pol_dipole_former) + pt_mode%omega(ii)* &
211 (this%pt_q(ii) + this%pt_q_former(ii)))*pt_mode%lambda(ii)
212 call lalg_axpy(gr%np, -vmf_coeff, pt_mode%pol_dipole(:, ii), this%vmf)
214 this%fmf(jj) = this%fmf(jj) - pt_mode%omega(ii)*pt_mode%lambda(ii)* &
215 pt_mode%pol(ii, jj)*(this%pt_q(ii) + lambda_pol_dipole/pt_mode%omega(ii))
219 if (first .and. this%has_restart)
then
223 this%time_former = time*pt_mode%mu
232 type(
mf_t),
intent(in) :: this
234 real(real64),
intent(in) :: dt
236 integer,
intent(out) :: ierr
238 character(len=80),
allocatable :: lines(:)
239 integer :: iunit, err, jj, ions_dim
242 ions_dim = gr%box%dim
244 safe_allocate(lines(1:2*ions_dim + 4))
248 iunit = restart%open(
'photon_mf')
249 write(lines(1),
'(a10,2x,es19.12)')
'pt_integral_real', real(this%integral(1))
250 write(lines(2),
'(a10,2x,es19.12)')
'pt_integral_aimag', aimag(this%integral(1))
251 write(lines(3),
'(a10,2x,es19.12)')
'pt_q_former', this%pt_q_former(1)
252 write(lines(4),
'(a10,2x,es19.12)')
'pt_time_former', this%time_former - dt*pt_mode%mu
254 write(lines(4 + jj),
'(a10,2x,es19.12)')
'dipole', this%dipole(jj)
257 write(lines(4 + ions_dim + jj),
'(a10,2x,es19.12)')
'dipole_former', this%dipole_former(jj)
259 call restart%write(iunit, lines, 2*ions_dim + 4, err)
260 if (err /= 0) ierr = ierr + 1
261 call restart%close(iunit)
263 safe_deallocate_a(lines)
272 type(
mf_t),
intent(inout) :: this
273 type(
grid_t),
intent(in) :: gr
274 integer,
intent(out) :: ierr
276 integer :: err, iunit, jj, ions_dim
277 character(len=128),
allocatable :: lines(:)
278 character(len=7) :: dummy
279 real(real64),
allocatable :: rr(:)
284 ions_dim = gr%box%dim
286 if (restart%skip())
then
292 message(1) =
"Debug: Reading Photons restart."
295 safe_allocate(rr(1:2*ions_dim + 4))
296 safe_allocate(lines(1:2*ions_dim + 4))
297 iunit = restart%open(
'photon_mf')
298 call restart%read(iunit, lines, 2*ions_dim + 4, err)
302 do jj = 1, 2*ions_dim + 4
303 read(lines(jj),
'(a10,2x,es19.12)') dummy, rr(jj)
306 this%integral(1) = cmplx(rr(1), rr(2), real64)
307 this%pt_q_former(1) = rr(3)
308 this%time_former = rr(4)
310 this%dipole(jj) = rr(jj + 4)
313 this%dipole_former(jj) = rr(jj + ions_dim + 4)
315 this%has_restart = .
true.
318 call restart%close(iunit)
320 message(1) =
"Debug: Reading Photons restart done."
323 safe_deallocate_a(rr)
324 safe_deallocate_a(lines)
constant times a vector plus a vector
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_zero
complex(real64), parameter, public m_zi
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
This module implements the underlying real-space grid.
This module defines various routines, operating on mesh functions.
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)
subroutine, public mf_photons_load(restart, this, gr, ierr)
subroutine, public mf_init(this, gr, st, ions, pt_mode)
subroutine, public mf_photons_dump(restart, this, gr, dt, pt_mode, ierr)
subroutine, public mf_end(this)
subroutine, public mf_calc(this, gr, st, ions, pt_mode, time)
subroutine, public photon_mode_compute_dipoles(this, mesh)
Computes the polarization dipole.
Description of the grid, containing information on derivatives, stencil, and symmetries.