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(:,:)
73 real(real64),
allocatable :: rotated_omega(:)
75 logical :: has_q0_p0 = .false.
82 type(photon_mode_t),
intent(out) :: this
83 type(namespace_t),
intent(in) :: namespace
84 integer,
intent(in) :: dim
85 logical,
optional,
intent(in) :: photon_free
88 integer :: ii, idir, iunit, ncols
89 logical :: file_exists
90 character(256) :: filename
97 this%has_q0_p0 = .false.
110 call parse_variable(namespace,
'PhotonmodesFilename',
'photonmodes', filename)
111 inquire(file=trim(filename), exist=file_exists)
112 if (file_exists)
then
114 message(1) =
'Opening '//trim(filename)
117 iunit =
io_open(trim(filename), namespace, action=
'read', form=
'formatted')
120 read(iunit, *) this%nmodes, ncols
122 write(
message(1),
'(3a,i7,a,i3,a)')
'Reading file ', trim(filename),
' with ', &
123 this%nmodes,
' photon modes and ', ncols,
' columns.'
126 safe_allocate(this%omega(1:this%nmodes))
127 safe_allocate(this%lambda(1:this%nmodes))
128 safe_allocate(this%pol(1:this%nmodes,1:3))
131 do ii = 1, this%nmodes
133 read(iunit, *) this%omega(ii), this%lambda(ii), &
134 this%pol(ii,1), this%pol(ii,2), this%pol(ii,3)
135 else if (ncols == 7)
then
136 this%has_q0_p0 = .
true.
137 if (.not.
associated(this%pt_coord_q0))
then
138 safe_allocate(this%pt_coord_q0(1:this%nmodes))
140 if (.not.
associated(this%pt_momen_p0))
then
141 safe_allocate(this%pt_momen_p0(1:this%nmodes))
143 read(iunit, *) this%omega(ii), this%lambda(ii), &
144 this%pol(ii,1), this%pol(ii,2), this%pol(ii,3), &
145 this%pt_coord_q0(ii), this%pt_momen_p0(ii)
148 message(1) =
'Error: unexpected number of columns in file:'
154 this%pol(ii,:) = this%pol(ii,:)/norm2(this%pol(ii,:))
162 safe_allocate(this%omega(1:this%nmodes))
163 safe_allocate(this%lambda(1:this%nmodes))
164 safe_allocate(this%pol(1:this%nmodes,1:3))
166 safe_allocate(this%pt_coord_q0(1:this%nmodes))
167 safe_allocate(this%pt_momen_p0(1:this%nmodes))
170 call mpi_world%bcast(this%omega(1), this%nmodes, mpi_double_precision, 0)
171 call mpi_world%bcast(this%lambda(1), this%nmodes, mpi_double_precision, 0)
172 call mpi_world%bcast(this%pol(1,1), this%nmodes*3, mpi_double_precision, 0)
174 call mpi_world%bcast(this%pt_coord_q0(1), this%nmodes, mpi_double_precision, 0)
175 call mpi_world%bcast(this%pt_momen_p0(1), this%nmodes, mpi_double_precision, 0)
179 call messages_write(
'You need to specify the correct external photon modes file')
203 if (.not. file_exists)
then
204 if (
parse_block(namespace,
'PhotonModes', blk) == 0)
then
207 safe_allocate(this%omega(1:this%nmodes))
208 safe_allocate(this%lambda(1:this%nmodes))
209 safe_allocate(this%pol(1:this%nmodes, 1:this%dim))
213 do ii = 1, this%nmodes
219 do idir = 1, this%dim
223 if (ncols > this%dim + 2)
then
224 this%has_q0_p0 = .
true.
225 if (.not.
associated(this%pt_coord_q0))
then
226 safe_allocate(this%pt_coord_q0(1:this%nmodes))
228 if (.not.
associated(this%pt_momen_p0))
then
229 safe_allocate(this%pt_momen_p0(1:this%nmodes))
235 if ((ncols /= this%dim + 2) .and. (ncols /= this%dim + 4))
then
240 this%pol(ii,:) = this%pol(ii,:)/norm2(this%pol(ii,:))
272 call parse_variable(namespace,
'TDPhotonicTimeScale', 1.0_real64, this%mu)
275 safe_allocate(this%number(1:this%nmodes))
279 this%use_photon_exchange = .false.
282 if (this%use_photon_exchange)
then
283 safe_allocate(this%dressed_omega(1:this%nmodes))
284 safe_allocate(this%dressed_lambda(1:this%nmodes))
285 safe_allocate(this%dressed_pol(1:this%dim, 1:this%nmodes))
286 safe_allocate(this%rotated_omega(1:this%nmodes))
298 safe_deallocate_a(this%correlator)
300 safe_deallocate_a(this%omega)
301 safe_deallocate_a(this%lambda)
302 safe_deallocate_a(this%number)
304 safe_deallocate_a(this%pol)
305 safe_deallocate_a(this%pol_dipole)
307 if (this%has_q0_p0)
then
308 safe_deallocate_p(this%pt_coord_q0)
309 safe_deallocate_p(this%pt_momen_p0)
312 if (this%use_photon_exchange)
then
313 safe_deallocate_a(this%dressed_omega)
314 safe_deallocate_a(this%dressed_lambda)
315 safe_deallocate_a(this%dressed_pol)
316 safe_deallocate_a(this%rotated_omega)
325 integer,
optional,
intent(in) :: iunit
326 type(
namespace_t),
optional,
intent(in) :: namespace
333 write(iunit,
'(6x,a,10x,a,3x)', advance=
'no')
'Omega',
'Lambda'
334 write(iunit,
'(1x,a,i1,a)') (
'Pol.(', idir,
')', idir = 1, this%dim)
335 do im = 1, this%nmodes
336 write(iunit,
'(1x,f14.12)', advance=
'no') this%omega(im)
337 write(iunit,
'(1x,f14.12)', advance=
'no') this%lambda(im)
338 write(iunit,
'(2X,f5.3,1X)') (this%pol(im, idir), idir = 1, this%dim)
348 real(real64),
intent(in) :: qtot
352 this%n_electrons = qtot
361 class(
mesh_t),
intent(in) :: mesh
367 safe_allocate(this%pol_dipole(1:mesh%np, 1:this%nmodes))
369 do i = 1, this%nmodes
372 this%pol_dipole(ip, i) = dot_product(this%pol(i, 1:this%dim), mesh%x(ip, 1:this%dim))
382 type(
mesh_t),
intent(in) :: mesh
383 real(real64),
intent(in) :: rho(:)
384 real(real64),
intent(inout) :: pot(:)
387 real(real64) :: lx, ld, dipole(mesh%box%dim)
392 assert(this%nmodes == 1)
396 ld = dot_product(this%pol(1, 1:this%dim), dipole(1:this%dim))*this%lambda(1)
399 lx = this%pol_dipole(ip, 1)*this%lambda(1)
400 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
411 real(real64) :: eps_epsp, wmat_off
412 real(real64),
allocatable :: wmat(:,:)
413 real(real64),
allocatable :: dressed_omega_sq(:)
414 real(real64),
allocatable :: lambda_pol(:,:)
415 real(real64),
allocatable :: dressed_lambda_pol(:,:)
419 safe_allocate(wmat(1:this%nmodes,1:this%nmodes))
420 safe_allocate(dressed_omega_sq(1:this%nmodes))
421 safe_allocate(lambda_pol(1:this%nmodes,1:this%dim))
422 safe_allocate(dressed_lambda_pol(1:this%dim, 1:this%nmodes))
425 do ia = 1, this%nmodes
426 lambda_pol(ia, 1:this%dim) = this%lambda(ia) * this%pol(ia, 1:this%dim)
430 do ia = 1, this%nmodes
431 do iap = ia, this%nmodes
432 eps_epsp = dot_product(this%pol(ia, 1:this%dim), this%pol(iap, 1:this%dim))
434 wmat_off = this%n_electrons * this%lambda(ia) * this%lambda(iap) * eps_epsp
435 wmat(ia,iap) = wmat_off
436 wmat(iap,ia) = wmat_off
438 wmat(ia,ia) = this%omega(ia)**2 + wmat(ia,ia)
444 do ia = 1, this%nmodes
445 this%dressed_omega(ia) =
sqrt(dressed_omega_sq(ia))
449 call dgemm(
'T',
'N', this%dim, this%nmodes, this%nmodes,&
450 m_one, lambda_pol, this%nmodes, &
455 do ia = 1, this%nmodes
456 this%dressed_lambda(ia) = norm2(dressed_lambda_pol(1:this%dim, ia))
458 if (this%dressed_lambda(ia) .lt.
m_epsilon)
THEN
460 this%dressed_pol(1:this%dim, ia) =
m_zero
462 this%dressed_pol(1:this%dim, ia) = dressed_lambda_pol(1:this%dim, ia)/this%dressed_lambda(ia)
467 this%rotated_omega =
m_zero
469 do ia = 1, this%nmodes
470 this%rotated_omega(ia) =
sqrt(this%dressed_omega(ia)**2 - this%n_electrons * this%dressed_lambda(ia)**2)
473 safe_deallocate_a(wmat)
474 safe_deallocate_a(dressed_omega_sq)
475 safe_deallocate_a(lambda_pol)
476 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
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, 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)
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.