LCOV - code coverage report
Current view: top level - src/77_ddb - m_ddb_diel.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.0 % 344 282
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 4 4

            Line data    Source code
       1              : !!****m* ABINIT/m_ddb_diel
       2              : !! NAME
       3              : !! m_ddb_diel
       4              : !!
       5              : !! FUNCTION
       6              : !! This module provides routines for the calculation of the dielectric constant (anaddb)
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 1999-2026 ABINIT group (XG,XW, MVeithen, EB)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_ddb_diel
      23              : 
      24              :  use defs_basis
      25              :  use m_errors
      26              :  use m_xmpi
      27              :  use m_abicore
      28              :  use m_ddb
      29              :  use m_nctk
      30              :  use netcdf
      31              : 
      32              :  use m_anaddb_dataset, only : anaddb_dataset_type
      33              :  use m_crystal,        only : crystal_t
      34              : 
      35              :  implicit none
      36              : 
      37              :  private
      38              : !!***
      39              : 
      40              :  public :: ddb_diel
      41              :  public :: alignph
      42              : !!***
      43              : 
      44              : contains
      45              : !!***
      46              : 
      47              : !!****f* ABINIT/ddb_diel
      48              : !!
      49              : !! NAME
      50              : !! ddb_diel
      51              : !!
      52              : !! FUNCTION
      53              : !! Get the frequency-dependent dielectric matrix, as well as the
      54              : !! oscillator strengths and mode effective charges,
      55              : !! and reflectivities (without damping)
      56              : !! See the definitions Eq.(53-54) in PRB55, 10355 (1997) [[cite:Gonze1997a]].
      57              : !!
      58              : !! INPUTS
      59              : !! amu(ntypat)=mass of the atoms (atomic mass unit)
      60              : !! anaddb_dtset= (derived datatype) contains all the input variables
      61              : !! matrix (diagonal in the atoms)
      62              : !! displ(2,3*natom,3*natom)=
      63              : !!  the displacements of atoms in cartesian coordinates.
      64              : !!  The first index means either the real or the imaginary part,
      65              : !!  The second index runs on the direction and the atoms displaced
      66              : !!  The third index runs on the modes.
      67              : !! d2cart(2,3,mpert,3,mpert)=dynamical matrix, effective charges, dielectric tensor,... all in cartesian coordinates
      68              : !! iout=unit number for outputs
      69              : !! lst(3*nph2l)=log. of product of frequencies**2, needed to calculate
      70              : !!  the generalized Lyddane-Sachs-Teller relation at zero frequency
      71              : !! mpert =maximum number of ipert
      72              : !! natom=number of atoms in unit cell
      73              : !! nph2l=input variable from anaddb_dtset, needed to dimension lst
      74              : !! phfrq(3*natom)=phonon frequencies (square root of the dynamical
      75              : !!  matrix eigenvalues, except if these are negative, and in this
      76              : !!  case, give minus the square root of the absolute value
      77              : !!  of the matrix eigenvalues). Hartree units.
      78              : !! comm=MPI communicator.
      79              : !! ncid=the id of the open NetCDF file. Set to nctk_noid if netcdf output is not wanted.
      80              : !!
      81              : !! OUTPUT
      82              : !! fact_oscstr(2,3,3*natom)=oscillator strengths for the different eigenmodes,
      83              : !!  for different direction of the electric field;
      84              : !! dielt_rlx(3,3) relaxed ion (zero frequency) dielectric tensor.
      85              : !!
      86              : !! NOTES
      87              : !! 1. The phonon frequencies phfrq should correspond to the
      88              : !! wavevector at Gamma, without any non-analyticities.
      89              : !! 2. Should clean for no imaginary part ...
      90              : !! This routine should be used only by one processor.
      91              : !! 3. frdiel(3,3,nfreq)= frequency-dependent dielectric tensor
      92              : !! mode effective charges for the different eigenmodes,
      93              : !! for different direction of the electric field
      94              : !!
      95              : !! SOURCE
      96              : 
      97           26 : subroutine ddb_diel(Crystal,amu,anaddb_dtset,dielt_rlx,displ,d2cart,epsinf,fact_oscstr,&
      98           26 : & iout,lst,mpert,natom,nph2l,phfrq,comm,ncid)
      99              : 
     100              : !Arguments -------------------------------
     101              : !scalars
     102              :  integer,intent(in) :: iout,mpert,natom,nph2l,comm,ncid
     103              :  type(crystal_t),intent(in) :: Crystal
     104              :  type(anaddb_dataset_type),intent(in) :: anaddb_dtset
     105              :  real(dp),intent(in) :: lst(nph2l+1)
     106              : 
     107              : !arrays
     108              :  real(dp),intent(in) :: amu(Crystal%ntypat),d2cart(2,3,mpert,3,mpert)
     109              :  real(dp),intent(in) :: phfrq(3*natom),epsinf(3,3)
     110              :  real(dp),intent(inout) :: displ(2,3*natom,3*natom)
     111              :  real(dp),intent(out) :: dielt_rlx(3,3),fact_oscstr(2,3,3*natom)
     112              : 
     113              : !Local variables -------------------------
     114              : !scalars
     115              :  integer,parameter :: master=0
     116              :  integer :: dieflag,idir1,idir2,ifreq,ii,imode,iphl2,nfreq
     117              :  integer :: nprocs,my_rank,ncerr
     118              :  real(dp) :: afreq,difffr,eps,q2,ucvol
     119              :  character(len=500) :: message
     120              : !arrays
     121              :  real(dp) :: qphon(3),refl(3)
     122           26 :  real(dp),allocatable :: frdiel(:,:,:),modez(:,:,:),oscstr(:,:,:,:),dielt_modedecompo(:,:,:)
     123              : 
     124              : ! *********************************************************************
     125              : 
     126           26 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     127              : 
     128           26 :  dieflag=anaddb_dtset%dieflag
     129           26 :  nfreq=anaddb_dtset%nfreq
     130              : 
     131           26 :  ucvol = Crystal%ucvol
     132              : 
     133              : 
     134              : ! frdiel(3,3,nfreq)= frequency-dependent dielectric tensor
     135              : ! modez=mode effective charge
     136           78 :  ABI_MALLOC(frdiel,(3,3,nfreq))
     137          104 :  ABI_MALLOC(oscstr,(2,3,3,3*natom))
     138           78 :  ABI_MALLOC(modez,(2,3,3*natom))
     139           78 :  ABI_MALLOC(dielt_modedecompo,(3,3,3*natom))
     140              : 
     141              : !In case only the electronic dielectric constant should be printed
     142           26 :  if (dieflag==2) then
     143            7 :    call ddb_diel_elec(iout,epsinf)
     144              :  else
     145              : !  In case the ionic contribution to the dielectric tensor is asked
     146           19 :    if (dieflag/=2 .and. nph2l==0) then
     147              : !   Check if the alignement of phonon modes eigenvector is requested from the input flag alphon;
     148              : !   useful in case of degenerate modes
     149           10 :      if (anaddb_dtset%alphon > 0) then
     150              :        write(message, '(3a)' )&
     151            3 :         ' The alphon input variable is non-zero, will mix the degenerate phonon modes',ch10,&
     152            6 :         ' in order to align the mode effective charges with the cartesian axes.'
     153            3 :        call wrtout(std_out,message,'COLL')
     154            3 :        call wrtout(iout,message,'COLL')
     155            3 :        call alignph(amu,displ,d2cart,mpert,natom,Crystal%ntypat,phfrq,Crystal%typat)
     156              :      end if ! alignment of the phonon eigenvectors
     157              : 
     158              : !    Compute the mode effective charge and oscillator strength
     159           10 :      call ddb_oscstr(displ,d2cart,fact_oscstr,oscstr,modez,iout,mpert,natom,phfrq,ncid,my_rank)
     160              : 
     161              : !      Calculation of epsilon_r (Eq.55 PRB 55, 10355)
     162              : !      Check the acousticity of the three lowest modes, assuming
     163              : !      that they are ordered correctly
     164           10 :        if (abs(phfrq(1))>abs(phfrq(4)))then
     165              : !        This means that there is at least one mode with truly negative frequency
     166              :          write(message, '(12a,4es16.8)' )&
     167            0 :            'The lowest mode appears to be a "true" negative mode,',ch10,&
     168            0 :            'and not an acoustic mode. This precludes the computation',ch10,&
     169            0 :            'of the frequency-dependent dielectric tensor.',ch10,&
     170            0 :            'Action : likely there is no action to be taken, although you,',ch10,&
     171            0 :            'could try to raise your convergence parameters (ecut and k-points).',ch10,&
     172            0 :            'For your information, here are the four lowest frequencies :',ch10,&
     173            0 :            (phfrq(ii),ii=1,4)
     174            0 :          ABI_ERROR(message)
     175              :        end if
     176              : 
     177              : !      Compute the relaxed ion dielectric tensor
     178           40 :        do idir1=1,3
     179          130 :          do idir2=1,3
     180              : !          The electronic contribution to epsilon is added
     181           90 :            dielt_rlx(idir1,idir2)=epsinf(idir1,idir2)
     182              : !          calculation of the phonon contribution (ionic) to epsilon
     183         1227 :            do imode=4,3*natom
     184              : !            Note that the acoustic modes are not included : their
     185              : !            oscillator strength should be exactly zero
     186              : !            Also, only the real part of oscstr is taken into account:
     187              : !            the possible imaginary parts of degenerate modes
     188              : !            will cancel.
     189              :              dielt_rlx(idir1,idir2)=dielt_rlx(idir1,idir2)+&
     190         1107 : &             oscstr(1,idir1,idir2,imode) / (phfrq(imode)**2)*four_pi/ucvol
     191              : !            Mode decomposition of epsilon
     192         1197 :              if (dieflag==3)then
     193            0 :                dielt_modedecompo(idir1,idir2,imode)=oscstr(1,idir1,idir2,imode) / (phfrq(imode)**2)*four_pi/ucvol
     194              :              endif ! mode decompo of epsilon
     195              : !DEBUG
     196              : !         if(idir1==1 .and. idir2==2)then
     197              : !           write(std_out,'(a,i4,a,3es16.6)')'imode=',imode,' dielt_rlx(idir1,idir2),oscstr(1,idir1,idir2,imode),phfrq(imode)=',&
     198              : !&            dielt_rlx(idir1,idir2),oscstr(1,idir1,idir2,imode),phfrq(imode)
     199              : !         endif
     200              : !ENDDEBUG
     201              :            end do ! imode
     202              :          end do ! idir2
     203              :        end do ! idir1
     204              : 
     205              :        ! Print the electronic dielectric tensor
     206           10 :        call ddb_diel_elec(iout,epsinf)
     207              : 
     208              :        ! Print the relaxed ion dielectric tensor
     209           10 :        write(message,'(a,a)') ch10,' Relaxed ion dielectric tensor'
     210           10 :        call wrtout(std_out,message,'COLL')
     211           10 :        call wrtout(iout,message,'COLL')
     212              : 
     213           40 :        do idir1=1,3
     214           30 :          write(message,'(3f16.8)')(dielt_rlx(idir1,idir2),idir2=1,3)
     215           30 :          call wrtout(std_out,message,'COLL')
     216           40 :          call wrtout(iout,message,'COLL')
     217              :        end do
     218           10 :        call wrtout(iout, " ",'COLL')
     219           10 :        call wrtout(std_out, " ",'COLL')
     220              : 
     221              : !      Mode decompo of epsilon
     222           10 :        if (dieflag==3) then
     223            0 :          write(message,'(a,a,a,a)') ch10,' Mode by mode decomposition of the ionic dielectric tensor',&
     224            0 :                                     ch10,' (the electronic contribution is not included)'
     225            0 :          call wrtout(std_out,message,'COLL')
     226            0 :          call wrtout(iout,message,'COLL')
     227            0 :          do imode=4,3*natom
     228            0 :            write(message,'(a,a,i4,a,es14.6,a,a,3f8.3)') ch10,' Mode number ',imode, '    freq = ',phfrq(imode),' Ha', &
     229            0 :                                                           '   Mode Z* (|x|, |y|, |z|)', (abs(modez(1,idir1,imode)),idir1=1,3)
     230            0 :            call wrtout(std_out,message,'COLL')
     231            0 :            call wrtout(iout,message,'COLL')
     232            0 :            do idir1=1,3
     233              :            ! write(message,'(a,a,i4)') ch10,' Mode number 2',imode
     234            0 :              write(message,'(3f16.8)')(dielt_modedecompo(idir1,idir2,imode),idir2=1,3)
     235            0 :              call wrtout(std_out,message,'COLL')
     236            0 :              call wrtout(iout,message,'COLL')
     237              :            end do
     238              :          end do
     239              :        endif ! mode decompo of epsilon
     240              : 
     241              :        ! write the relaxed ion dielectric tensor to the netcdf
     242           10 :        if (ncid /= nctk_noid) then
     243              :          ncerr = nctk_def_arrays(ncid, [nctkarr_t("emacro_cart_rlx", "dp", &
     244           20 :          "number_of_cartesian_directions, number_of_cartesian_directions")],defmode=.True.)
     245           10 :          NCF_CHECK(ncerr)
     246           10 :          NCF_CHECK(nctk_set_datamode(ncid))
     247           10 :          NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "emacro_cart_rlx"), dielt_rlx))
     248              :        end if
     249              : 
     250              : !    Frequency-dependent dielectric tensor case
     251           10 :      if(dieflag==1) then
     252            8 :        write(message,'(4a)') ch10,ch10,' Calculate the freq. dep. dielectric constant',ch10
     253            8 :        call wrtout(std_out,message,'COLL')
     254            8 :        write(message,'(3a)') ch10,' Frequency dependent dielectric constant:',ch10
     255            8 :        call wrtout(iout,message,'COLL')
     256              : 
     257              : !      Check the possibility of asking the frequency-dependent
     258              : !      dielectric tensor (there should be more than one atom in the unit cell)
     259              : !      EB: this check is not in any automatic test
     260            8 :        if(natom==1)then
     261              :          write(message, '(6a)' )&
     262            0 :            ' ddb_diel : WARNING -',ch10,&
     263            0 :            '  When there is only one atom in the unit cell',ch10,&
     264            0 :            '  cell, the dielectric tensor is frequency-independent.'!,&
     265              : !           '  Consequently, dieflag has been reset to 2 . '
     266            0 :          call wrtout(std_out,message,'COLL')
     267            0 :          call wrtout(iout,message,'COLL')
     268              :        end if
     269              : 
     270            8 :        difffr=zero
     271            8 :        if(nfreq>1)difffr=(anaddb_dtset%frmax-anaddb_dtset%frmin)/(nfreq-1)
     272              : 
     273            2 :        if (nfreq>10 .and. my_rank == master) then
     274              :          write(iout, '(a,a,a,a,a,a,a,a)' )&
     275            2 :           ' ddb_diel : the number of frequencies is larger',&
     276            2 :           ' than 10 => I will consider only',ch10,&
     277            2 :           ' the three principal directions, assume that the tensor',ch10,&
     278            2 :           ' is diagonalized, and give dielectric constant and ',ch10,&
     279            4 :           ' reflectivities.'
     280              :          write(iout, '(a,a)' )&
     281            2 :           ' Frequency(Hartree)    Dielectric constant   ',&
     282            4 :           '             Reflectivity    '
     283              :          write(iout, '(a,a)' )&
     284            2 :           '                     x           y          z',&
     285            4 :           '          x        y        z'
     286              :        end if
     287              : 
     288              : !      Loop on frequencies
     289          214 :        do ifreq=1,nfreq
     290          206 :          afreq=anaddb_dtset%frmin+difffr*(ifreq-1)
     291          824 :          do idir1=1,3
     292         2678 :            do idir2=1,3
     293         1854 :              frdiel(idir1,idir2,ifreq)=epsinf(idir1,idir2)
     294         8817 :              do imode=4,3*natom
     295              : !              Note that the acoustic modes are not included : their
     296              : !              oscillator strength should be exactly zero
     297              : !              Also, only the real part of oscstr is taken into account:
     298              : !              the possible imaginary parts of degenerate modes
     299              : !              will cancel.
     300              :                frdiel(idir1,idir2,ifreq)=frdiel(idir1,idir2,ifreq)+&
     301         8199 : &               oscstr(1,idir1,idir2,imode) / (phfrq(imode)**2-afreq**2)*four_pi/ucvol
     302              :              end do
     303              :            end do
     304              :          end do
     305              : 
     306              :         ! Write all this information (actually, there should be a choice of units for the frequencies ...
     307          214 :         if (nfreq>10) then
     308          800 :           do idir1=1,3
     309          800 :             if(frdiel(idir1,idir1,ifreq)<=zero)then
     310           24 :               refl(idir1)=one
     311              :             else
     312              : !             See Gervais and Piriou PRB11,3944(1975) [[cite:Gervais1975]].
     313          576 :               refl(idir1)=( (sqrt(frdiel(idir1,idir1,ifreq)) -one) /(sqrt(frdiel(idir1,idir1,ifreq)) +one) )**2
     314              :             end if
     315              :           end do
     316          200 :           if (my_rank == master) then
     317          800 :             write(iout, '(7es12.4)' )afreq,(frdiel(idir1,idir1,ifreq),idir1=1,3),(refl(idir1),idir1=1,3)
     318              :           end if
     319              : 
     320              :         else
     321            6 :           if (my_rank == master) then
     322            6 :             write(iout, '(a,es12.4,a)' )' Full dielectric tensor at frequency',afreq,' Hartree'
     323           24 :             do idir1=1,3
     324           24 :               write(iout, '(3f16.8)' ) (frdiel(idir1,idir2,ifreq),idir2=1,3)
     325              :             end do
     326            6 :             write(iout, '(a)' )' '
     327              :           end if
     328              :         end if
     329              : 
     330              :       end do ! End of the loop on frequencies
     331              :     end if ! End the condition on frequency-dependent dielectric tensor (dieflag=1)
     332              :   end if ! dieflag/=2 .and. nph2l==0
     333              : end if
     334              : 
     335              : !Calculation of the Lyddane-Sachs-Teller value of the dielectric constant at zero frequency
     336           26 : if(nph2l/=0 .and. dieflag/=2) then
     337              : 
     338              : !  Prepare the output
     339            9 :    write(message, '(a,a,a,a)' ) ch10,&
     340            9 :     ' Generalized Lyddane-Sachs-Teller relation at zero frequency :',ch10,&
     341           18 :     ' Direction                     Dielectric constant'
     342            9 :    call wrtout(std_out,message,'COLL')
     343            9 :    call wrtout(iout,message,'COLL')
     344              : 
     345              : !  Examine every wavevector in the phonon list
     346           23 :    do iphl2=1,anaddb_dtset%nph2l
     347              : 
     348           56 :      qphon(1:3)=anaddb_dtset%qph2l(1:3,iphl2)
     349              : 
     350           23 :      if(abs(qphon(1))>DDB_QTOL .or. abs(qphon(2))>DDB_QTOL .or. abs(qphon(3))>DDB_QTOL)then
     351           14 :        q2=qphon(1)**2+qphon(2)**2+qphon(3)**2
     352              :        eps=qphon(1)**2*epsinf(1,1)+qphon(2)**2*epsinf(2,2)+&
     353              : &      qphon(3)**2*epsinf(3,3)+ 2* ( qphon(1)*qphon(2)*epsinf(1,2)+&
     354           14 : &      qphon(1)*qphon(3)*epsinf(1,3)+qphon(2)*qphon(3)*epsinf(2,3))
     355           14 :        eps=eps/q2*exp(lst(iphl2)-lst(anaddb_dtset%nph2l+1))
     356           14 :        if (my_rank == master) then
     357           14 :          write(iout, '(3f10.5,f16.8)' )qphon,eps
     358           14 :          write(std_out,'(3f10.5,f16.8)' )qphon,eps
     359              :        end if
     360              :      end if
     361              :    end do
     362              :  end if ! End of the condition of nph2l does not vanish for Lyddane-Sachs-Teller
     363              : 
     364              : 
     365           26 :  ABI_FREE(frdiel)
     366           26 :  ABI_FREE(modez)
     367           26 :  ABI_FREE(oscstr)
     368           26 :  ABI_FREE(dielt_modedecompo)
     369              : 
     370           26 : end subroutine ddb_diel
     371              : !!***
     372              : 
     373              : 
     374              : 
     375              : !!****f* ABINIT/ddb_diel_elec
     376              : !!
     377              : !! NAME
     378              : !! ddb_diel_elec
     379              : !!
     380              : !! FUNCTION
     381              : !! Print the electronic dielectric constant (clamped ions)
     382              : !!
     383              : !! INPUTS
     384              : !! iout=unit number for outputs
     385              : !! epsinf(3,3)= epsilon^infty = electronic contribution to the
     386              : !!  dielectric tensor
     387              : !!
     388              : !! OUTPUT
     389              : !!
     390              : !! SOURCE
     391              : 
     392           17 : subroutine ddb_diel_elec(iout,epsinf)
     393              : 
     394              : !Arguments -------------------------------
     395              : !scalars
     396              :  integer,intent(in) :: iout
     397              : !arrays
     398              :  real(dp),intent(in) :: epsinf(3,3)
     399              : 
     400              : !Local variables -------------------------
     401              : !scalars
     402              :  integer :: idir1,idir2
     403              :  character(len=500) :: message
     404              : !arrays
     405              : 
     406           17 :  write(message, '(a,a)' ) ch10,' Electronic dielectric tensor'
     407           17 :  call wrtout(std_out,message,'COLL')
     408           17 :  call wrtout(iout,message,'COLL')
     409              : 
     410              :  !Compute the electronic contribution to the dielectric tensor
     411              :  !Needs only the perturbations with E-field from the DDB
     412           68 :  do idir1=1,3
     413              : !   do idir2=1,3
     414              : !     epsinf(idir1,idir2)=d2cart(1,idir1,natom+2,idir2,natom+2)
     415              : !   end do
     416           51 :    write(message, '(3f16.8)' )(epsinf(idir1,idir2),idir2=1,3)
     417           51 :    call wrtout(std_out,message,'COLL')
     418           68 :    call wrtout(iout,message,'COLL')
     419              :  end do
     420           17 :  call wrtout(iout, " ",'COLL')
     421           17 :  call wrtout(std_out, " ",'COLL')
     422              : 
     423           17 : end subroutine ddb_diel_elec
     424              : !!***
     425              : 
     426              : 
     427              : 
     428              : !!****f* ABINIT/ddb_oscstr
     429              : !!
     430              : !! NAME
     431              : !! ddb_oscstr
     432              : !!
     433              : !! FUNCTION
     434              : !! Compute the oscillator strength and the mode effective charge
     435              : !!
     436              : !! INPUTS
     437              : !! displ(2,3*natom,3*natom)=
     438              : !!  the displacements of atoms in cartesian coordinates.
     439              : !!  The first index means either the real or the imaginary part,
     440              : !!  The second index runs on the direction and the atoms displaced
     441              : !!  The third index runs on the modes.
     442              : !! d2cart(2,3,mpert,3,mpert)=
     443              : !!  dynamical matrix, effective charges, dielectric tensor,....
     444              : !!  all in cartesian coordinates
     445              : !! iout=unit number for outputs
     446              : !! mpert =maximum number of ipert
     447              : !! natom=number of atoms in unit cell
     448              : !! phfrq(3*natom)=phonon frequencies (square root of the dynamical
     449              : !!  matrix eigenvalues, except if these are negative, and in this
     450              : !!  case, give minus the square root of the absolute value
     451              : !!  of the matrix eigenvalues). Hartree units.
     452              : !!
     453              : !! OUTPUT
     454              : !! fact_oscstr(2,3,3*natom)=oscillator strengths for the different eigenmodes,
     455              : !!  for different direction of the electric field.
     456              : !! modez(2,3,3*natom)=mode effective charges for the different eigenmodes,
     457              : !!  for different directions of the electric field, following
     458              : !!  the definition Eq.(53) in PRB55, 10355 (1997) [[cite:Gonze1997a]]
     459              : !! oscstr(2,3,3,3*natom)=oscillator strengths, following
     460              : !!  the definition Eq.(54) in PRB55, 10355 (1997) [[cite:Gonze1997a]]
     461              : !!
     462              : !! SOURCE
     463              : 
     464           10 : subroutine ddb_oscstr(displ,d2cart,fact_oscstr,oscstr,modez,iout,mpert,natom,phfrq,ncid,my_rank)
     465              : 
     466              : !Arguments -------------------------------
     467              : !scalars
     468              :  integer,intent(in) :: iout,mpert,natom,ncid,my_rank
     469              : !arrays
     470              :  real(dp),intent(in) :: d2cart(2,3,mpert,3,mpert)
     471              :  real(dp),intent(in) :: phfrq(3*natom)
     472              :  real(dp),intent(inout) :: displ(2,3*natom,3*natom)
     473              :  real(dp),intent(out) :: fact_oscstr(2,3,3*natom),oscstr(2,3,3,3*natom),modez(2,3,3*natom)
     474              : 
     475              : !Local variables -------------------------
     476              : !scalars
     477              :  integer,parameter :: master=0
     478              :  integer :: i1,idir1,idir2,imode,ipert1
     479              :  integer :: ncerr
     480              :  real(dp) :: usquare
     481              :  logical :: t_degenerate
     482              : !arrays
     483           10 :  character(len=1),allocatable :: metacharacter(:)
     484              : 
     485              : ! *********************************************************************
     486              : 
     487              : !  Get the factors of the oscillator strength, and the mode effective charge for each mode
     488          163 :    do imode=1,3*natom
     489              :      usquare=zero
     490         3438 :      do i1=1,3*natom
     491         3438 :        usquare=usquare+displ(1,i1,imode)*displ(1,i1,imode)+displ(2,i1,imode)*displ(2,i1,imode)
     492              :      end do
     493          622 :      do idir2=1,3
     494         1377 :        fact_oscstr(:,idir2,imode)=zero
     495         1377 :        modez(:,idir2,imode)=zero
     496         1989 :        do idir1=1,3
     497        11691 :          do ipert1=1,natom
     498         9855 :            i1=idir1+(ipert1-1)*3
     499              :            fact_oscstr(:,idir2,imode)=fact_oscstr(:,idir2,imode)+&
     500        29565 : &           displ(:,i1,imode)*d2cart(1,idir1,ipert1,idir2,natom+2)
     501              :            modez(:,idir2,imode)=modez(:,idir2,imode)+&
     502              : &           displ(:,i1,imode)*&
     503        30942 : &           d2cart(1,idir1,ipert1,idir2,natom+2)/sqrt(usquare)
     504              :          end do
     505              :        end do
     506              :      end do
     507              :    end do
     508              : 
     509              : !  Examine the degeneracy of each mode. The portability of the echo of the mode effective
     510              : !  charges and oscillator strengths is very hard to guarantee. On the contrary,
     511              : !  the scalar reductions of these quantities are OK.
     512           40 :    ABI_MALLOC(metacharacter,(3*natom))
     513          163 :    do imode=1,3*natom
     514              : !    The degenerate modes are not portable
     515          153 :      t_degenerate=.false.
     516          153 :      if(imode>1)then
     517          143 :        if(phfrq(imode)-phfrq(imode-1)<tol6)t_degenerate=.true.
     518              :      end if
     519          153 :      if(imode<3*natom)then
     520          143 :        if(phfrq(imode+1)-phfrq(imode)<tol6)t_degenerate=.true.
     521              :      end if
     522          153 :      metacharacter(imode)=';'
     523          163 :      if(t_degenerate)metacharacter(imode)='-'
     524              :    end do
     525              : 
     526           10 :    if (my_rank == master) then
     527              :      !  Write the mode effective charge for each mode
     528           10 :      write(iout, '(a)' )'  '
     529           10 :      write(iout, '(a)' )' Mode effective charges '
     530           10 :      write(iout, '(a)' )' Mode number.    x            y            z            length '
     531          163 :      do imode=1,3*natom
     532          153 :        write(iout, '(a,i6,a,4f13.6)' )metacharacter(imode),imode,'     ',(modez(1,idir1,imode),idir1=1,3),&
     533          316 : &                                   (sqrt(modez(1,1,imode)**2+modez(1,2,imode)**2+modez(1,3,imode)**2))
     534              :      end do
     535              :    end if ! master
     536              : 
     537              : !  Get the oscillator strengths
     538          163 :    do imode=1,3*natom
     539          622 :      do idir1=1,3
     540         1989 :        do idir2=1,3
     541              :          oscstr(1,idir1,idir2,imode)= &
     542              : &         fact_oscstr(1,idir1,imode)*fact_oscstr(1,idir2,imode) +&
     543         1377 : &         fact_oscstr(2,idir1,imode)*fact_oscstr(2,idir2,imode)
     544         1377 :          if(abs(oscstr(1,idir1,idir2,imode))<tol14)oscstr(1,idir1,idir2,imode)=zero
     545              : 
     546              : !DEBUG
     547              : !         if(idir1==1 .and. idir2==2)then
     548              : !           write(std_out,'(a,i4,a,5es16.6)')'imode=',imode,&
     549              : !&           ' oscstr(1,idir1,idir2,imode), fact_oscstr(:,idir1,imode),fact_oscstr(:,idir2,imode)=',&
     550              : !&            oscstr(1,idir1,idir2,imode), fact_oscstr(:,idir1,imode),fact_oscstr(:,idir2,imode)
     551              : !         endif
     552              : !ENDDEBUG
     553              : 
     554              :          oscstr(2,idir1,idir2,imode)= &
     555              : &         fact_oscstr(1,idir1,imode)*fact_oscstr(2,idir2,imode) -&
     556         1377 : &         fact_oscstr(2,idir1,imode)*fact_oscstr(1,idir2,imode)
     557         1836 :          if(abs(oscstr(2,idir1,idir2,imode))<tol14)oscstr(2,idir1,idir2,imode)=zero
     558              :        end do
     559              :      end do
     560              :    end do
     561              : 
     562           10 :    if (my_rank == master) then
     563              :      !  Write the oscillator strength for each mode
     564           10 :      write(iout, '(a)' )'  '
     565           10 :      write(iout, '(a)' )' Oscillator strengths (in a.u. ; 1 a.u.=253.2638413 m3/s2). Set to zero if abs()<tol14.'
     566           10 :      write(iout, '(a)' )' Mode number.       xx          yy          zz          xy          xz          yz          trace'
     567          163 :      do imode=1,3*natom
     568              :        write(iout, '(a,i4,a,7es12.4)' )&
     569          765 : &       metacharacter(imode),imode,'     Real  ',(oscstr(1,idir1,idir1,imode),idir1=1,3),&
     570          153 : &       oscstr(1,1,2,imode), oscstr(1,1,3,imode),oscstr(1,2,3,imode),&
     571          918 : &       ((oscstr(1,1,1,imode)+oscstr(1,2,2,imode)+oscstr(1,3,3,imode)))
     572              :        write(iout, '(a,a,6es12.4)' )&
     573          765 : &       metacharacter(imode),'         Imag  ',(oscstr(2,idir1,idir1,imode),idir1=1,3),&
     574          928 : &       oscstr(2,1,2,imode),oscstr(2,1,3,imode),oscstr(2,2,3,imode)
     575              :      end do
     576              : 
     577              :      ! write the oscillator strength to the netcdf
     578           10 :      if (ncid /= nctk_noid) then
     579              :        ncerr = nctk_def_arrays(ncid, [nctkarr_t("oscillator_strength", "dp", &
     580              :        "complex, number_of_cartesian_directions, number_of_cartesian_directions, number_of_phonon_modes")], &
     581           20 :        defmode=.True.)
     582           10 :        NCF_CHECK(ncerr)
     583           10 :        NCF_CHECK(nctk_set_datamode(ncid))
     584           10 :        NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "oscillator_strength"), oscstr))
     585              :      end if
     586              :    end if
     587              : 
     588           10 :    ABI_FREE(metacharacter)
     589              : 
     590           10 : end subroutine ddb_oscstr
     591              : !!***
     592              : 
     593              : 
     594              : 
     595              : !!****f* ABINIT/alignph
     596              : !!
     597              : !! NAME
     598              : !! alignph
     599              : !!
     600              : !! FUNCTION
     601              : !! Construct linear combinations of the phonon eigendisplacements
     602              : !! of degenerate modes in order to align the mode effective charges
     603              : !! along the axes of the cartesian frame.
     604              : !!
     605              : !! INPUTS
     606              : !! amu(ntypat)=mass of the atoms (atomic mass unit)
     607              : !! displ(2,3*natom,3*natom)=
     608              : !! the displacements of atoms in cartesian coordinates.
     609              : !! The first index means either the real or the imaginary part,
     610              : !! The second index runs on the direction and the atoms displaced
     611              : !! The third index runs on the modes.
     612              : !! d2cart(2,3,mpert,3,mpert)=
     613              : !!  dynamical matrix, effective charges, dielectric tensor,....
     614              : !!  all in cartesian coordinates
     615              : !! mpert =maximum number of ipert
     616              : !! natom=number of atoms in unit cell
     617              : !! ntypat=number of types of atoms
     618              : !! phfrq(3*natom)=phonon frequencies (square root of the dynamical
     619              : !!  matrix eigenvalues, except if these are negative, and in this
     620              : !!  case, give minus the square root of the absolute value
     621              : !!  of the matrix eigenvalues). Hartree units.
     622              : !! typat(natom)=integer label of each type of atom (1,2,...)
     623              : !!
     624              : !! OUTPUT
     625              : !! displ(2,3*natom,3*natom)=
     626              : !!  the displacements of atoms in cartesian coordinates.
     627              : !!  The eigendisplacements of degenerate modes have been aligned along
     628              : !!  the cartesian axes.
     629              : !!
     630              : !! SOURCE
     631              : 
     632           33 : subroutine alignph(amu,displ,d2cart,mpert,natom,ntypat,phfrq,typat, &
     633              :                    silent) !optional
     634              : 
     635              : !Arguments -------------------------------
     636              : !scalars
     637              :  integer,intent(in) :: mpert,natom,ntypat
     638              :  integer,optional,intent(in) :: silent
     639              : !arrays
     640              :  integer,intent(in) :: typat(natom)
     641              :  real(dp),intent(in) :: amu(ntypat),d2cart(2,3,mpert,3,mpert),phfrq(3*natom)
     642              :  real(dp),intent(inout) :: displ(2,3*natom,3*natom)
     643              : 
     644              : !Local variables -------------------------
     645              : !scalars
     646              :  integer,parameter :: master=0
     647              :  integer :: i1,idir1,idir2,ii,imode,imodex,imodey,imodez,ipert1,silent_
     648              :  real(dp) :: theta
     649              : !arrays
     650           33 :  integer,allocatable :: deg(:)
     651              :  real(dp) :: zvec(3,3),zvect(3,3)
     652           33 :  real(dp),allocatable :: modez(:,:,:),modezabs(:),oscstr(:,:,:),vec(:,:),vect(:,:)
     653              : 
     654              : ! *********************************************************************
     655              : 
     656              : !Reduce verbosity
     657           33 :  silent_=0
     658           33 :  if (present(silent)) silent_=silent
     659              : 
     660              : !Get the oscillator strength and mode effective charge for each mode
     661          132 :  ABI_MALLOC(oscstr,(2,3,3*natom))
     662           66 :  ABI_MALLOC(modez,(2,3,3*natom))
     663           99 :  ABI_MALLOC(modezabs,(3*natom))
     664          132 :  ABI_MALLOC(vec,(3*natom,3))
     665           66 :  ABI_MALLOC(vect,(3*natom,3))
     666           99 :  ABI_MALLOC(deg,(3*natom))
     667              : 
     668           33 :  if (silent_/=1) then
     669            3 :    write(std_out,'(a,a)')ch10,' alignph : before modifying the eigenvectors, mode number and mode effective charges :'
     670              :  end if
     671          591 :  do imode=1,3*natom
     672          558 :    modezabs(imode)=zero
     673         1674 :    do ii=1,2
     674         5022 :      do idir2=1,3
     675         3348 :        oscstr(ii,idir2,imode)=zero
     676         3348 :        modez(ii,idir2,imode)=zero
     677        13392 :        do idir1=1,3
     678        72360 :          do ipert1=1,natom
     679        58968 :            i1=idir1+(ipert1-1)*3
     680              :            oscstr(ii,idir2,imode)=oscstr(ii,idir2,imode)+&
     681              : &           displ(ii,i1,imode)*&
     682        58968 : &           d2cart(1,idir1,ipert1,idir2,natom+2)
     683              :            modez(ii,idir2,imode)=modez(ii,idir2,imode)+&
     684              : &           displ(ii,i1,imode)*&
     685              : &           d2cart(1,idir1,ipert1,idir2,natom+2)*&
     686        69012 : &           sqrt(amu(typat(ipert1))*amu_emass)
     687              :          end do
     688              :        end do
     689         4464 :        if(abs(modez(ii,idir2,imode))>modezabs(imode))modezabs(imode)=abs(modez(ii,idir2,imode))
     690              :      end do
     691              :    end do
     692          591 :    if (silent_/=1) write(std_out,'(i4,3f16.6)')imode,modez(1,:,imode)
     693              :  end do
     694              : 
     695              : !Find degenerate modes with non-zero mode effective charge
     696           33 :  imode = 0
     697          482 :  do while (imode < 3*natom)
     698          449 :    imode = imode + 1
     699          482 :    if (imode == 3*natom) then
     700           10 :      deg(imode) = 1
     701          439 :    else if (abs(phfrq(imode) - phfrq(imode+1)) > tol6 .or. modezabs(imode)<tol8 .or. modezabs(imode+1)<tol8) then
     702              : !    Differ by phonon frequency or zero mode effective charge
     703          336 :      deg(imode) = 1
     704              :    else
     705          103 :      deg(imode) = 2
     706          103 :      if (imode < 3*natom - 1) then
     707           83 :        if (abs(phfrq(imode) - phfrq(imode+2)) < tol6 .and. modezabs(imode+2)>tol8) then
     708            6 :          deg(imode) = 3
     709            6 :          imode = imode + 1
     710              :        end if
     711              :      end if
     712          103 :      imode = imode + 1
     713              :    end if
     714              :  end do
     715              : 
     716              : 
     717              : !In case of a degenerate mode, with non-zero mode effective charge, align the mode effective charge vector along
     718              : !the axes of the cartesian frame
     719           33 :  imode = 1
     720          482 :  do while (imode <= 3*natom)
     721              : 
     722          449 :    if (silent_/=1) then
     723            6 :      write(std_out,'(a,a,i4,a,i2)')ch10,' Mode number ',imode,' has degeneracy ',deg(imode)
     724            6 :      write(std_out,'(a,3es16.6)') ' Mode effective charge of this mode =',modez(1,:,imode)
     725              :    end if
     726              : 
     727          449 :    if (deg(imode) == 2) then
     728              : 
     729              : !    Optimize on the x direction
     730           97 :      if (silent_/=1) then
     731            0 :        write(std_out,'(a,3es16.6)') ' Mode effective charge of next mode =',modez(1,:,imode+1)
     732              :      end if
     733           97 :      if (abs(modez(1,1,imode)) > tol8) then
     734           95 :        theta = atan(-modez(1,1,imode+1)/modez(1,1,imode))
     735         1805 :        vec(:,1) = displ(1,:,imode)
     736         1805 :        vec(:,2) = displ(1,:,imode+1)
     737         1805 :        displ(1,:,imode) = cos(theta)*vec(:,1) - sin(theta)*vec(:,2)
     738         1805 :        displ(1,:,imode+1) = sin(theta)*vec(:,1) + cos(theta)*vec(:,2)
     739              : 
     740              : !      MR: Rotate also the imaginary part
     741         1805 :        vec(:,1) = displ(2,:,imode)
     742         1805 :        vec(:,2) = displ(2,:,imode+1)
     743         1805 :        displ(2,:,imode) = cos(theta)*vec(:,1) - sin(theta)*vec(:,2)
     744         1805 :        displ(2,:,imode+1) = sin(theta)*vec(:,1) + cos(theta)*vec(:,2)
     745              : 
     746              :      end if
     747              : 
     748          352 :    else if (deg(imode) == 3) then
     749              : 
     750            6 :      if (silent_/=1) then
     751            6 :        write(std_out,'(a,3es16.6)') ' Mode effective charge of next mode =',modez(1,:,imode+1)
     752            6 :        write(std_out,'(a,3es16.6)') ' Mode effective charge of next-next mode =',modez(1,:,imode+2)
     753              :      end if
     754              : 
     755              : !    Before mixing them, select the mode-effective charge vectors as being predominently "x", "y" or "z" type.
     756            0 :      if(abs(modez(1,1,imode))>abs(modez(1,2,imode))-tol12 .and. &
     757            6 : &     abs(modez(1,1,imode))>abs(modez(1,3,imode))-tol12) then
     758            0 :        imodex=imode
     759            0 :        if(abs(modez(1,2,imode+1))>abs(modez(1,3,imode+1))-tol12)then
     760            0 :          imodey=imode+1 ; imodez=imode+2
     761              :        else
     762            0 :          imodez=imode+1 ; imodey=imode+2
     763              :        end if
     764            6 :      else if(abs(modez(1,2,imode))>abs(modez(1,1,imode))-tol12 .and. &
     765            6 : &       abs(modez(1,2,imode))>abs(modez(1,3,imode))-tol12) then
     766            0 :        imodey=imode
     767            0 :        if(abs(modez(1,1,imode+1))>abs(modez(1,3,imode+1))-tol12)then
     768            0 :          imodex=imode+1 ; imodez=imode+2
     769              :        else
     770            0 :          imodez=imode+1 ; imodex=imode+2
     771              :        end if
     772              :      else
     773            6 :        imodez=imode
     774            6 :        if(abs(modez(1,1,imode+1))>abs(modez(1,2,imode+1))-tol12)then
     775            0 :          imodex=imode+1 ; imodey=imode+2
     776              :        else
     777            6 :          imodey=imode+1 ; imodex=imode+2
     778              :        end if
     779              :      end if
     780           42 :      vec(:,1)=displ(1,:,imodex)
     781           42 :      vec(:,2)=displ(1,:,imodey)
     782           42 :      vec(:,3)=displ(1,:,imodez)
     783           24 :      zvec(:,1)=modez(1,:,imodex)
     784           24 :      zvec(:,2)=modez(1,:,imodey)
     785           24 :      zvec(:,3)=modez(1,:,imodez)
     786              : 
     787              : 
     788              : !    Optimize along x : does the first vector has a component along x ?
     789            6 :      if (abs(zvec(1,1)) > tol8) then
     790              : !      Optimize on the (1,2) pair of modes along x
     791            6 :        theta = atan(-zvec(1,2)/zvec(1,1))
     792            6 :        zvect(:,:)=zvec(:,:)
     793           24 :        zvec(:,1) = cos(theta)*zvect(:,1) - sin(theta)*zvect(:,2)
     794           24 :        zvec(:,2) = sin(theta)*zvect(:,1) + cos(theta)*zvect(:,2)
     795          132 :        vect(:,:)=vec(:,:)
     796           42 :        vec(:,1) = cos(theta)*vect(:,1) - sin(theta)*vect(:,2)
     797           42 :        vec(:,2) = sin(theta)*vect(:,1) + cos(theta)*vect(:,2)
     798              : !      Optimize on the (1,3) pair of modes along x
     799            6 :        theta = atan(-zvec(1,3)/zvec(1,1))
     800            6 :        zvect(:,:)=zvec(:,:)
     801           24 :        zvec(:,1) = cos(theta)*zvect(:,1) - sin(theta)*zvect(:,3)
     802           24 :        zvec(:,3) = sin(theta)*zvect(:,1) + cos(theta)*zvect(:,3)
     803          132 :        vect(:,:)=vec(:,:)
     804           42 :        vec(:,1) = cos(theta)*vect(:,1) - sin(theta)*vect(:,3)
     805           42 :        vec(:,3) = sin(theta)*vect(:,1) + cos(theta)*vect(:,3)
     806            6 :        if (abs(zvec(2,2)) > tol8) then
     807              : !        Optimize on the (2,3) pair of modes along y
     808            6 :          theta = atan(-zvec(2,3)/zvec(2,2))
     809            6 :          zvect(:,:)=zvec(:,:)
     810           24 :          zvec(:,2) = cos(theta)*zvect(:,2) - sin(theta)*zvect(:,3)
     811           24 :          zvec(:,3) = sin(theta)*zvect(:,2) + cos(theta)*zvect(:,3)
     812          132 :          vect(:,:)=vec(:,:)
     813           42 :          vec(:,2) = cos(theta)*vect(:,2) - sin(theta)*vect(:,3)
     814           42 :          vec(:,3) = sin(theta)*vect(:,2) + cos(theta)*vect(:,3)
     815              :        end if
     816              : !    Likely, the remaining is not needed ... because the vectors have been ordered in x, y, and z major component ...
     817              : !    Optimize along x : does the second vector has a component along x ?
     818            0 :      else if(abs(zvec(1,2)) > tol8) then
     819              : !      Optimize on the (2,3) pair of modes along x
     820            0 :        theta = atan(-zvec(1,3)/zvec(1,2))
     821            0 :        zvect(:,:)=zvec(:,:)
     822            0 :        zvec(:,2) = cos(theta)*zvect(:,2) - sin(theta)*zvect(:,3)
     823            0 :        zvec(:,3) = sin(theta)*zvect(:,2) + cos(theta)*zvect(:,3)
     824            0 :        vect(:,:)=vec(:,:)
     825            0 :        vec(:,2) = cos(theta)*vect(:,2) - sin(theta)*vect(:,3)
     826            0 :        vec(:,3) = sin(theta)*vect(:,2) + cos(theta)*vect(:,3)
     827              : !      Optimize on the (1,3) pair of modes along y
     828            0 :        if (abs(zvec(2,1)) > tol8) then
     829            0 :          theta = atan(-zvec(2,3)/zvec(2,1))
     830            0 :          zvect(:,:)=zvec(:,:)
     831            0 :          zvec(:,1) = cos(theta)*zvect(:,1) - sin(theta)*zvect(:,3)
     832            0 :          zvec(:,3) = sin(theta)*zvect(:,1) + cos(theta)*zvect(:,3)
     833            0 :          vect(:,:)=vec(:,:)
     834            0 :          vec(:,1) = cos(theta)*vect(:,1) - sin(theta)*vect(:,3)
     835            0 :          vec(:,3) = sin(theta)*vect(:,1) + cos(theta)*vect(:,3)
     836              :        end if
     837              : !    We are left with the pair of vectors (2,3)
     838            0 :      else if (abs(zvec(2,2)) > tol8) then
     839              : !      Optimize on the (2,3) pair of modes along y
     840            0 :        theta = atan(-zvec(2,3)/zvec(2,2))
     841            0 :        zvect(:,:)=zvec(:,:)
     842            0 :        zvec(:,2) = cos(theta)*zvect(:,2) - sin(theta)*zvect(:,3)
     843            0 :        zvec(:,3) = sin(theta)*zvect(:,2) + cos(theta)*zvect(:,3)
     844            0 :        vect(:,:)=vec(:,:)
     845            0 :        vec(:,2) = cos(theta)*vect(:,2) - sin(theta)*vect(:,3)
     846            0 :        vec(:,3) = sin(theta)*vect(:,2) + cos(theta)*vect(:,3)
     847              :      end if
     848              : 
     849           42 :      displ(1,:,imodex)=vec(:,1)
     850           42 :      displ(1,:,imodey)=vec(:,2)
     851           42 :      displ(1,:,imodez)=vec(:,3)
     852              : 
     853              : !    Previous coding, from Marek. Apparently, break the orthogonalization of vectors ...
     854              : !    do ii = 1,3
     855              : !      coeff(:) = 0._dp
     856              : !      if (ii == 1) then
     857              : !        jj = 2 ; kk = 3
     858              : !      else if (ii == 2) then
     859              : !        jj = 1 ; kk = 3
     860              : !      else
     861              : !        jj = 1 ; kk = 2
     862              : !      end if
     863              : !      coeff(ii) = 1._dp
     864              : !      c1 = modez(1,jj,imode+ii-1)
     865              : !      c2 = modez(1,jj,imode+jj-1)
     866              : !      c3 = modez(1,jj,imode+kk-1)
     867              : !      c4 = modez(1,kk,imode+ii-1)
     868              : !      c5 = modez(1,kk,imode+jj-1)
     869              : !      c6 = modez(1,kk,imode+kk-1)
     870              : !      dtm = c2*c6 - c3*c5
     871              : !      if (abs(dtm) > tol8) then
     872              : !        coeff(jj) = (c3*c4 - c1*c6)/dtm
     873              : !        coeff(kk) = (c1*c5 - c2*c4)/dtm
     874              : !      end if
     875              : !      mod_ = sqrt(1._dp + coeff(jj)*coeff(jj) + coeff(kk)*coeff(kk))
     876              : !      coeff(:) = coeff(:)/mod_
     877              : !      displ(1,:,imode+ii-1) = coeff(1)*vec(1,:) + coeff(2)*vec(2,:) + &
     878              : !&       coeff(3)*vec(3,:)
     879              : !    end do
     880              : 
     881              :    end if ! if deg mode
     882              : 
     883          449 :    imode = imode + deg(imode)
     884              : 
     885              :  end do
     886              : 
     887           33 :  if (silent_/=1) then
     888            3 :    write(std_out,'(a,a)')ch10,' alignph : after modifying the eigenvectors, mode number and mode effective charges :'
     889              :  end if
     890          591 :  do imode=1,3*natom
     891         1674 :    do ii=1,2
     892         5022 :      do idir2=1,3
     893         3348 :        modez(ii,idir2,imode)=zero
     894        14508 :        do idir1=1,3
     895        72360 :          do ipert1=1,natom
     896        58968 :            i1=idir1+(ipert1-1)*3
     897              :            modez(ii,idir2,imode)=modez(ii,idir2,imode)+&
     898              : &           displ(ii,i1,imode)*&
     899              : &           d2cart(1,idir1,ipert1,idir2,natom+2)*&
     900        69012 : &           sqrt(amu(typat(ipert1))*amu_emass)
     901              :          end do
     902              :        end do
     903              :      end do
     904              :    end do
     905          591 :    if (silent_/=1)  write(std_out,'(i4,3f16.6)')imode,modez(1,:,imode)
     906              :  end do
     907              : 
     908           33 :  ABI_FREE(deg)
     909           33 :  ABI_FREE(oscstr)
     910           33 :  ABI_FREE(modez)
     911           33 :  ABI_FREE(modezabs)
     912           33 :  ABI_FREE(vec)
     913           33 :  ABI_FREE(vect)
     914              : 
     915           33 : end subroutine alignph
     916              : !!***
     917              : 
     918              : end module m_ddb_diel
     919              : !!***
        

Generated by: LCOV version 2.3-1