29 use,
intrinsic :: iso_fortran_env
57 real(real64),
allocatable :: omega(:)
58 real(real64),
allocatable :: lambda(:)
59 real(real64),
allocatable :: pol(:,:)
60 real(real64),
allocatable :: pol_dipole(:,:)
62 real(real64),
allocatable :: number(:)
63 real(real64),
allocatable :: correlator(:,:)
64 real(real64) :: n_electrons
65 real(real64),
pointer :: pt_coord_q0(:) => null()
66 real(real64),
pointer :: pt_momen_p0(:) => null()
69 logical :: use_photon_exchange
70 real(real64),
allocatable :: dressed_omega(:)
71 real(real64),
allocatable :: dressed_lambda(:)
72 real(real64),
allocatable :: dressed_pol(:,:)
74 real(real64),
allocatable :: rotated_omega(:)
76 logical :: has_q0_p0 = .false.
83 type(photon_mode_t),
intent(out) :: this
84 type(namespace_t),
intent(in) :: namespace
85 integer,
intent(in) :: dim
86 logical,
optional,
intent(in) :: photon_free
89 integer :: ii, idir, iunit, ncols
90 logical :: file_exists
91 character(256) :: filename
98 this%has_q0_p0 = .false.
111 call parse_variable(namespace,
'PhotonmodesFilename',
'photonmodes', filename)
112 inquire(file=trim(filename), exist=file_exists)
113 if (file_exists)
then
115 message(1) =
'Opening '//trim(filename)
118 iunit =
io_open(trim(filename), namespace, action=
'read', form=
'formatted')
121 read(iunit, *) this%nmodes, ncols
123 write(
message(1),
'(3a,i7,a,i3,a)')
'Reading file ', trim(filename),
' with ', &
124 this%nmodes,
' photon modes and ', ncols,
' columns.'
127 safe_allocate(this%omega(1:this%nmodes))
128 safe_allocate(this%lambda(1:this%nmodes))
129 safe_allocate(this%pol(1:this%nmodes,1:3))
132 do ii = 1, this%nmodes
134 read(iunit, *) this%omega(ii), this%lambda(ii), &
135 this%pol(ii,1), this%pol(ii,2), this%pol(ii,3)
136 else if (ncols == 7)
then
137 this%has_q0_p0 = .
true.
138 if (.not.
associated(this%pt_coord_q0))
then
139 safe_allocate(this%pt_coord_q0(1:this%nmodes))
141 if (.not.
associated(this%pt_momen_p0))
then
142 safe_allocate(this%pt_momen_p0(1:this%nmodes))
144 read(iunit, *) this%omega(ii), this%lambda(ii), &
145 this%pol(ii,1), this%pol(ii,2), this%pol(ii,3), &
146 this%pt_coord_q0(ii), this%pt_momen_p0(ii)
149 message(1) =
'Error: unexpected number of columns in file:'
155 this%pol(ii,:) = this%pol(ii,:)/norm2(this%pol(ii,:))
161 call mpi_world%bcast(ncols, 1, mpi_integer, 0)
163 safe_allocate(this%omega(1:this%nmodes))
164 safe_allocate(this%lambda(1:this%nmodes))
165 safe_allocate(this%pol(1:this%nmodes,1:3))
167 safe_allocate(this%pt_coord_q0(1:this%nmodes))
168 safe_allocate(this%pt_momen_p0(1:this%nmodes))
171 call mpi_world%bcast(this%omega(1), this%nmodes, mpi_double_precision, 0)
172 call mpi_world%bcast(this%lambda(1), this%nmodes, mpi_double_precision, 0)
173 call mpi_world%bcast(this%pol(1,1), this%nmodes*3, mpi_double_precision, 0)
175 call mpi_world%bcast(this%pt_coord_q0(1), this%nmodes, mpi_double_precision, 0)
176 call mpi_world%bcast(this%pt_momen_p0(1), this%nmodes, mpi_double_precision, 0)
180 call messages_write(
'You need to specify the correct external photon modes file')
204 if (.not. file_exists)
then
205 if (
parse_block(namespace,
'PhotonModes', blk) == 0)
then
208 safe_allocate(this%omega(1:this%nmodes))
209 safe_allocate(this%lambda(1:this%nmodes))
210 safe_allocate(this%pol(1:this%nmodes, 1:this%dim))
214 do ii = 1, this%nmodes
220 do idir = 1, this%dim
224 if (ncols > this%dim + 2)
then
225 this%has_q0_p0 = .
true.
226 if (.not.
associated(this%pt_coord_q0))
then
227 safe_allocate(this%pt_coord_q0(1:this%nmodes))
229 if (.not.
associated(this%pt_momen_p0))
then
230 safe_allocate(this%pt_momen_p0(1:this%nmodes))
236 if ((ncols /= this%dim + 2) .and. (ncols /= this%dim + 4))
then
241 this%pol(ii,:) = this%pol(ii,:)/norm2(this%pol(ii,:))
273 call parse_variable(namespace,
'TDPhotonicTimeScale', 1.0_real64, this%mu)
276 safe_allocate(this%number(1:this%nmodes))
280 this%use_photon_exchange = .false.
283 if (this%use_photon_exchange)
then
284 safe_allocate(this%dressed_omega(1:this%nmodes))
285 safe_allocate(this%dressed_lambda(1:this%nmodes))
286 safe_allocate(this%dressed_pol(1:this%dim, 1:this%nmodes))
287 safe_allocate(this%rotated_omega(1:this%nmodes))
299 safe_deallocate_a(this%correlator)
301 safe_deallocate_a(this%omega)
302 safe_deallocate_a(this%lambda)
303 safe_deallocate_a(this%number)
305 safe_deallocate_a(this%pol)
306 safe_deallocate_a(this%pol_dipole)
308 if (this%has_q0_p0)
then
309 safe_deallocate_p(this%pt_coord_q0)
310 safe_deallocate_p(this%pt_momen_p0)
313 if (this%use_photon_exchange)
then
314 safe_deallocate_a(this%dressed_omega)
315 safe_deallocate_a(this%dressed_lambda)
316 safe_deallocate_a(this%dressed_pol)
317 safe_deallocate_a(this%rotated_omega)
326 integer,
optional,
intent(in) :: iunit
327 type(
namespace_t),
optional,
intent(in) :: namespace
334 write(iunit,
'(6x,a,10x,a,3x)', advance=
'no')
'Omega',
'Lambda'
335 write(iunit,
'(1x,a,i1,a)') (
'Pol.(', idir,
')', idir = 1, this%dim)
336 do im = 1, this%nmodes
337 write(iunit,
'(1x,f14.12)', advance=
'no') this%omega(im)
338 write(iunit,
'(1x,f14.12)', advance=
'no') this%lambda(im)
339 write(iunit,
'(2X,f5.3,1X)') (this%pol(im, idir), idir = 1, this%dim)
349 real(real64),
intent(in) :: qtot
353 this%n_electrons = qtot
362 class(
mesh_t),
intent(in) :: mesh
368 safe_allocate(this%pol_dipole(1:mesh%np, 1:this%nmodes))
370 do i = 1, this%nmodes
373 this%pol_dipole(ip, i) = dot_product(this%pol(i, 1:this%dim), mesh%x(ip, 1:this%dim))
383 type(
mesh_t),
intent(in) :: mesh
384 real(real64),
intent(in) :: rho(:)
385 real(real64),
intent(inout) :: pot(:)
388 real(real64) :: lx, ld, dipole(mesh%box%dim)
393 assert(this%nmodes == 1)
397 ld = dot_product(this%pol(1, 1:this%dim), dipole(1:this%dim))*this%lambda(1)
400 lx = this%pol_dipole(ip, 1)*this%lambda(1)
401 pot(ip) = pot(ip) - this%omega(1)/
sqrt(this%n_electrons)*(mesh%x(ip, this%dim + 1)*ld + lx*dipole(this%dim + 1)) + lx*ld
412 real(real64) :: eps_epsp, wmat_off
413 real(real64),
allocatable :: wmat(:,:)
414 real(real64),
allocatable :: dressed_omega_sq(:)
415 real(real64),
allocatable :: lambda_pol(:,:)
416 real(real64),
allocatable :: dressed_lambda_pol(:,:)
420 safe_allocate(wmat(1:this%nmodes,1:this%nmodes))
421 safe_allocate(dressed_omega_sq(1:this%nmodes))
422 safe_allocate(lambda_pol(1:this%nmodes,1:this%dim))
423 safe_allocate(dressed_lambda_pol(1:this%dim, 1:this%nmodes))
426 do ia = 1, this%nmodes
427 lambda_pol(ia, 1:this%dim) = this%lambda(ia) * this%pol(ia, 1:this%dim)
431 do ia = 1, this%nmodes
432 do iap = ia, this%nmodes
433 eps_epsp = dot_product(this%pol(ia, 1:this%dim), this%pol(iap, 1:this%dim))
435 wmat_off = this%n_electrons * this%lambda(ia) * this%lambda(iap) * eps_epsp
436 wmat(ia,iap) = wmat_off
437 wmat(iap,ia) = wmat_off
439 wmat(ia,ia) = this%omega(ia)**2 + wmat(ia,ia)
445 do ia = 1, this%nmodes
446 this%dressed_omega(ia) =
sqrt(dressed_omega_sq(ia))
450 call dgemm(
'T',
'N', this%dim, this%nmodes, this%nmodes,&
451 m_one, lambda_pol, this%nmodes, &
456 do ia = 1, this%nmodes
457 this%dressed_lambda(ia) = norm2(dressed_lambda_pol(1:this%dim, ia))
459 if (this%dressed_lambda(ia) .lt.
m_epsilon)
THEN
461 this%dressed_pol(1:this%dim, ia) =
m_zero
463 this%dressed_pol(1:this%dim, ia) = dressed_lambda_pol(1:this%dim, ia)/this%dressed_lambda(ia)
468 this%rotated_omega =
m_zero
470 do ia = 1, this%nmodes
471 this%rotated_omega(ia) =
sqrt(this%dressed_omega(ia)**2 - this%n_electrons * this%dressed_lambda(ia)**2)
474 safe_deallocate_a(wmat)
475 safe_deallocate_a(dressed_omega_sq)
476 safe_deallocate_a(lambda_pol)
477 safe_deallocate_a(dressed_lambda_pol)
real(real64), parameter, public m_zero
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_one
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
This module defines various routines, operating on mesh functions.
subroutine, public dmf_dipole(mesh, ff, dipole, mask)
This routine calculates the dipole of a function ff, for arbitrary dimensions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=512), private msg
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_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
type(mpi_grp_t), public mpi_world
logical function, public parse_is_defined(namespace, name)
integer function, public parse_block(namespace, name, blk, check_varinfo_)
subroutine, public photon_mode_compute_dipoles(this, mesh)
Computes the polarization dipole.
subroutine, public photon_mode_add_poisson_terms(this, mesh, rho, pot)
subroutine, public photon_mode_write_info(this, iunit, namespace)
subroutine, public photon_mode_end(this)
subroutine, public photon_mode_dressed(this)
subroutine, public photon_mode_set_n_electrons(this, qtot)
subroutine, public photon_mode_init(this, namespace, dim, photon_free)
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
Describes mesh distribution to nodes.