LCOV - code coverage report
Current view: top level - src/77_ddb - m_sortph.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.2 % 52 50
Test Date: 2026-09-21 22:40:37 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****m* ABINIT/m_sorth_ph
       2              : !! NAME
       3              : !!
       4              : !! FUNCTION
       5              : !!
       6              : !! COPYRIGHT
       7              : !!  Copyright (C) 2008-2026 ABINIT group (MVer, FDortu, MVeithen)
       8              : !!  This file is distributed under the terms of the
       9              : !!  GNU General Public License, see ~abinit/COPYING
      10              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      11              : !!
      12              : !! SOURCE
      13              : 
      14              : #if defined HAVE_CONFIG_H
      15              : #include "config.h"
      16              : #endif
      17              : 
      18              : #include "abi_common.h"
      19              : 
      20              : module m_sortph
      21              : 
      22              :  use defs_basis
      23              :  use m_abicore
      24              :  use m_errors
      25              : 
      26              :  use m_io_tools,   only : open_file
      27              : 
      28              :  implicit none
      29              : 
      30              :  private
      31              : 
      32              :  complex(dp),save,allocatable :: eigvecLast(:,:)
      33              : 
      34              :  public :: end_sortph
      35              :  public :: sortph
      36              : 
      37              :  ! Logical units used to write data.
      38              :  integer,private,save :: udispl=-1,ufreq=-1
      39              : !!***
      40              : 
      41              : contains
      42              : 
      43              : !!****f* m_sortph/end_sortph
      44              : !! NAME
      45              : !! end_sortph
      46              : !!
      47              : !! FUNCTION
      48              : !! Deallocate array for sortph
      49              : !!
      50              : !! INPUTS
      51              : !!
      52              : !! OUTPUT
      53              : !!  Only deallocation
      54              : !!
      55              : !! NOTES
      56              : !!
      57              : !! SOURCE
      58           79 : subroutine end_sortph()
      59              : 
      60           79 :  if (allocated(eigvecLast))  then
      61           12 :    ABI_FREE(eigvecLast)
      62              :  end if
      63              : 
      64           79 :  if (ufreq /= -1) then
      65           12 :    close(ufreq); ufreq = -1
      66              :  end if
      67           79 :  if (udispl /= -1) then
      68           12 :    close(udispl); udispl = -1
      69              :  end if
      70              : 
      71           79 : end subroutine end_sortph
      72              : !!***
      73              : 
      74              : !!****f* m_sortph/sortph
      75              : !! NAME
      76              : !! sortph
      77              : !!
      78              : !! FUNCTION
      79              : !! Sort the energies in order to have fine phonon dispersion curves
      80              : !! It is best not to include the gamma point in the list
      81              : !!
      82              : !! MODIFIED
      83              : !! Takeshi Nishimatsu
      84              : !!
      85              : !! INPUTS
      86              : !!  eigvec(2*3*natom*3*natom)= contain
      87              : !!  the eigenvectors of the dynamical matrix.
      88              : !!  displ(2*3*natom*3*natom)= contain
      89              : !!   the displacements of atoms in cartesian coordinates.
      90              : !!   The first index means either the real or the imaginary part,
      91              : !!   The second index runs on the direction and the atoms displaced
      92              : !!   The third index runs on the modes.
      93              : !!  filnam=name of output files
      94              : !!   hacmm1,hartev,harthz,xkb= different conversion factors
      95              : !!  natom= number of atom
      96              : !!  phfrq(3*natom)= phonon frequencies in Hartree
      97              : !!
      98              : !! OUTPUT
      99              : !!  (only writing ?)
     100              : !!
     101              : !! NOTES
     102              : !! Called by one processor only
     103              : !!
     104              : !! SOURCE
     105              : 
     106          588 : subroutine sortph(eigvec,displ,filnam, natom,phfrq)
     107              : 
     108              : !Arguments -----------------------------------
     109              : !scalars
     110              : integer,intent(in) :: natom
     111              : character(len=*),intent(in) :: filnam
     112              : !arrays
     113              : real(dp),intent(in) :: eigvec(2,3,natom,3,natom)
     114              : real(dp),intent(in) :: displ(2*3*natom*3*natom)
     115              : real(dp),intent(in) :: phfrq(3*natom)
     116              : 
     117              : !Local variables-------------------------------
     118              : !scalars
     119              : integer :: iatom,imode,j,idir1,idir2,ipert1,ipert2,i1,i2
     120              : character(len=fnlen) :: file_displ,file_freq
     121              : character(len=20) :: fmt_phfrq
     122              : character(len=500) :: msg
     123              : !arrays
     124         1176 : logical     ::               mask(3*natom)
     125         1176 : real(dp)    ::           phfrqNew(3*natom)
     126         1176 : complex(dp) ::           displIn(3*natom,3*natom)
     127         1176 : complex(dp) ::           displNew(3*natom,3*natom)
     128         1176 : complex(dp) ::           eigvecIn(3*natom,3*natom)
     129         1176 : complex(dp) ::          eigvecNew(3*natom,3*natom)
     130         1176 : complex(dp) ::   transpose_eigvec(3*natom,3*natom)
     131         1176 : real(dp)    ::     abs_similarity(3*natom,3*natom)  !|<displNew|displLast>|
     132              : ! *********************************************************************
     133              : 
     134         2276 : do ipert2=1,natom
     135         7340 :   do idir2=1,3
     136         5064 :     i2=idir2+(ipert2-1)*3
     137        23390 :     do ipert1=1,natom
     138        71616 :       do idir1=1,3
     139        49914 :         i1=idir1+(ipert1-1)*3
     140        49914 :         eigvecIn(i1,i2)=cmplx(eigvec(1,idir1,ipert1,idir2,ipert2),eigvec(2,idir1,ipert1,idir2,ipert2))
     141        66552 :         displIn(i1,i2)=cmplx(displ(1+2*(i1-1)+2*3*natom*(i2-1)),displ(2+2*(i1-1)+2*3*natom*(i2-1)))
     142              :       end do
     143              :     end do
     144              :   end do
     145              : end do
     146              : 
     147          588 :  if(.not.allocated(eigvecLast)) then
     148           12 :    file_freq  = trim(filnam)//".freq" !---------------------------------------------------
     149           12 :    write(std_out,'(a,a)' )' sortph : opening file ',trim(file_freq)
     150           12 :    if (open_file(file_freq,msg,newunit=ufreq,STATUS='replace',ACTION='write') /= 0) then
     151            0 :      ABI_ERROR(msg)
     152              :    end if
     153           12 :    file_displ = trim(filnam)//".displ" !--------------------------------------------------
     154           12 :    write(std_out,'(a,a)' )' sortph : opening file ',trim(file_displ)
     155           12 :    if (open_file(file_displ,msg,newunit=udispl,STATUS='replace',ACTION='write') /= 0) then
     156            0 :      ABI_ERROR(msg)
     157              :    end if
     158           60 :    ABI_MALLOC(eigvecLast,(3*natom,3*natom))
     159          108 :    phfrqNew(:)   =  phfrq(:)
     160          990 :    displNew(:,:) =  displIn(:,:)
     161          990 :    eigvecNew(:,:) = eigvecIn(:,:)
     162              :  else
     163              : !  Avoid gfortran 4.2.1 bug, with which you CANNOT conjg(transpose(displ))
     164        54576 :    transpose_eigvec = transpose(eigvecIn)
     165      1247040 :    abs_similarity = abs(matmul(conjg(transpose_eigvec),eigvecLast))
     166         5544 :    mask(:) = .true.
     167         5544 :    phfrqNew(:)   =  phfrq(:)
     168        54576 :    displNew(:,:) =  displIn(:,:)
     169        54576 :    eigvecNew(:,:) = eigvecIn(:,:)
     170              :  end if
     171              : 
     172              : 
     173              : !Write frequencies in a file
     174          588 :  write(fmt_phfrq,'(a,i3,a)') '(', 3*natom, 'e18.10)'
     175          588 :  write(ufreq,fmt_phfrq) (phfrqNew(j),j=1,3*natom)
     176              : 
     177              : !write displacements in a file
     178              : ! NB: sqrt still returns a complex number could be using modulus or something simpler
     179         5652 :    do imode=1,3*natom
     180        22290 :      do iatom=1,natom
     181              :        write(udispl,'(e18.10)') &
     182              :        real(sqrt(displNew(3*(iatom-1)+1,imode) * conjg(displNew(3*(iatom-1)+1,imode)) + &
     183              : &      displNew(3*(iatom-1)+2,imode) * conjg(displNew(3*(iatom-1)+2,imode)) + &
     184        21702 : &      displNew(3*(iatom-1)+3,imode) *  conjg(displNew(3*(iatom-1)+3,imode)) ))
     185              :      end do
     186              :    end do
     187              : 
     188        55566 :  eigvecLast(:,:) = eigvecNew(:,:)
     189              : 
     190          588 : end subroutine sortph
     191              : !!***
     192              : 
     193          576 : end module m_sortph
     194              : !!***
        

Generated by: LCOV version 2.3-1