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-11-06 14:42:53 Functions: 100.0 % 2 2
Branches: 73.8 % 122 90

             Branch data     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