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,:))
 
  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')
 
  205    if (.not. file_exists) 
then 
  206      if (
parse_block(namespace, 
'PhotonModes', blk) == 0) 
then 
  209        safe_allocate(this%omega(1:this%nmodes))
 
  210        safe_allocate(this%lambda(1:this%nmodes))
 
  211        safe_allocate(this%pol(1:this%nmodes, 1:this%dim))
 
  215        do ii = 1, this%nmodes
 
  221          do idir = 1, this%dim
 
  225          if (ncols > this%dim + 2) 
then 
  226            this%has_q0_p0 = .
true.
 
  227            if (.not. 
associated(this%pt_coord_q0)) 
then 
  228              safe_allocate(this%pt_coord_q0(1:this%nmodes))
 
  230            if (.not. 
associated(this%pt_momen_p0)) 
then 
  231              safe_allocate(this%pt_momen_p0(1:this%nmodes))
 
  237          if ((ncols /= this%dim + 2) .and. (ncols /= this%dim + 4)) 
then 
  242          this%pol(ii,:) = this%pol(ii,:)/norm2(this%pol(ii,:))
 
  274    call parse_variable(namespace, 
'TDPhotonicTimeScale', 1.0_real64, this%mu)
 
  277    safe_allocate(this%number(1:this%nmodes))
 
  281    this%use_photon_exchange = .false.
 
  284    if (this%use_photon_exchange) 
then 
  285      safe_allocate(this%dressed_omega(1:this%nmodes))
 
  286      safe_allocate(this%dressed_lambda(1:this%nmodes))
 
  287      safe_allocate(this%dressed_pol(1:this%dim, 1:this%nmodes))
 
  288      safe_allocate(this%rotated_omega(1:this%nmodes))
 
  300    safe_deallocate_a(this%correlator)
 
  302    safe_deallocate_a(this%omega)
 
  303    safe_deallocate_a(this%lambda)
 
  304    safe_deallocate_a(this%number)
 
  306    safe_deallocate_a(this%pol)
 
  307    safe_deallocate_a(this%pol_dipole)
 
  309    if (this%has_q0_p0) 
then 
  310      safe_deallocate_p(this%pt_coord_q0)
 
  311      safe_deallocate_p(this%pt_momen_p0)
 
  314    if (this%use_photon_exchange) 
then 
  315      safe_deallocate_a(this%dressed_omega)
 
  316      safe_deallocate_a(this%dressed_lambda)
 
  317      safe_deallocate_a(this%dressed_pol)
 
  318      safe_deallocate_a(this%rotated_omega)
 
  327    integer,             
optional, 
intent(in) :: iunit
 
  328    type(
namespace_t),   
optional, 
intent(in) :: namespace
 
  335    write(iunit, 
'(6x,a,10x,a,3x)', advance=
'no') 
'Omega', 
'Lambda' 
  336    write(iunit, 
'(1x,a,i1,a)') (
'Pol.(', idir, 
')', idir = 1, this%dim)
 
  337    do im = 1, this%nmodes
 
  338      write(iunit, 
'(1x,f14.12)', advance=
'no') this%omega(im)
 
  339      write(iunit, 
'(1x,f14.12)', advance=
'no') this%lambda(im)
 
  340      write(iunit, 
'(2X,f5.3,1X)') (this%pol(im, idir), idir = 1, this%dim)
 
  350    real(real64),        
intent(in)     :: qtot
 
  354    this%n_electrons = qtot
 
  363    class(
mesh_t),       
intent(in)     :: mesh
 
  369    safe_allocate(this%pol_dipole(1:mesh%np, 1:this%nmodes))
 
  371    do i = 1, this%nmodes
 
  374        this%pol_dipole(ip, i) = dot_product(this%pol(i, 1:this%dim), mesh%x(ip, 1:this%dim))
 
  384    type(
mesh_t),        
intent(in)    :: mesh
 
  385    real(real64),        
intent(in)    :: rho(:)
 
  386    real(real64),        
intent(inout) :: pot(:)
 
  389    real(real64) :: lx, ld, dipole(mesh%box%dim)
 
  394    assert(this%nmodes == 1)
 
  398    ld = dot_product(this%pol(1, 1:this%dim), dipole(1:this%dim))*this%lambda(1)
 
  401      lx = this%pol_dipole(ip, 1)*this%lambda(1)
 
  402      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
 
  413    real(real64) :: eps_epsp, wmat_off
 
  414    real(real64), 
allocatable :: wmat(:,:)
 
  415    real(real64), 
allocatable :: dressed_omega_sq(:)
 
  416    real(real64), 
allocatable :: lambda_pol(:,:)
 
  417    real(real64), 
allocatable :: dressed_lambda_pol(:,:)
 
  421    safe_allocate(wmat(1:this%nmodes,1:this%nmodes))
 
  422    safe_allocate(dressed_omega_sq(1:this%nmodes))
 
  423    safe_allocate(lambda_pol(1:this%nmodes,1:this%dim))
 
  424    safe_allocate(dressed_lambda_pol(1:this%dim, 1:this%nmodes))
 
  427    do ia = 1, this%nmodes
 
  428      lambda_pol(ia, 1:this%dim) = this%lambda(ia) * this%pol(ia, 1:this%dim)
 
  432    do ia = 1, this%nmodes
 
  433      do iap = ia, this%nmodes
 
  434        eps_epsp = dot_product(this%pol(ia, 1:this%dim), this%pol(iap, 1:this%dim))
 
  436        wmat_off = this%n_electrons * this%lambda(ia) * this%lambda(iap) * eps_epsp
 
  437        wmat(ia,iap) = wmat_off
 
  438        wmat(iap,ia) = wmat_off
 
  440      wmat(ia,ia) = this%omega(ia)**2 + wmat(ia,ia)
 
  446    do ia = 1, this%nmodes
 
  447      this%dressed_omega(ia) = 
sqrt(dressed_omega_sq(ia))
 
  451    call dgemm(
'T',
'N', this%dim, this%nmodes, this%nmodes,&
 
  452      m_one, lambda_pol, this%nmodes, &
 
  454      m_zero,dressed_lambda_pol,this%dim)
 
  457    do ia = 1, this%nmodes
 
  458      this%dressed_lambda(ia) = norm2(dressed_lambda_pol(1:this%dim, ia))
 
  460      if (this%dressed_lambda(ia) .lt. 
m_epsilon) 
THEN 
  462        this%dressed_pol(1:this%dim, ia) = 
m_zero 
  464        this%dressed_pol(1:this%dim, ia) = dressed_lambda_pol(1:this%dim, ia)/this%dressed_lambda(ia)
 
  469    this%rotated_omega = 
m_zero 
  471    do ia = 1, this%nmodes
 
  472      this%rotated_omega(ia) = 
sqrt(this%dressed_omega(ia)**2 - this%n_electrons * this%dressed_lambda(ia)**2)
 
  475    safe_deallocate_a(wmat)
 
  476    safe_deallocate_a(dressed_omega_sq)
 
  477    safe_deallocate_a(lambda_pol)
 
  478    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_new_line()
 
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)
 
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.