LCOV - code coverage report
Current view: top level - force - rotate_forces.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 35 36 97.2 %
Date: 2024-05-06 04:43:24 Functions: 1 1 100.0 %

          Line data    Source code
       1             : MODULE m_rotate_forces
       2             :    ! This routine writes a file similar to forces.dat, but containing
       3             :    ! all atoms in a sequence corresponding to their appearance in the
       4             :    ! input file for the input-file generator. forces.dat only
       5             :    ! contains forces for a representant of the symmetry equivalent
       6             :    ! atoms. This routine also gives files FORCES and POSCAR to be
       7             :    ! used with the phon package by Dario Alfe (for a single
       8             :    ! displacement),
       9             :    ! Reference
      10             :    ! Klueppelberg, Jun 2012
      11             : 
      12             :    ! Readded to only construct POSCAR and FORCES files in Dec 2020, Neukirchen
      13             : 
      14             :    ! Modified to construct a file for use with phonopy instead of PHON.
      15             :    ! Neukirchen, Dec 2020 
      16             : 
      17             : CONTAINS
      18           1 :    SUBROUTINE rotate_forces(ntypd,ntype,natd,nop,tote,omtil,neq,mrot,amat,bmat,taual,tau,force,label)
      19             :       USE m_constants
      20             :       USE m_juDFT_string
      21             : 
      22             :       IMPLICIT NONE
      23             : 
      24             :       INTEGER, INTENT (IN) :: ntypd,ntype,natd,nop
      25             :       REAL, INTENT (IN) :: tote,omtil
      26             : 
      27             :       INTEGER, INTENT (IN) :: neq(ntypd),mrot(3,3,nop)
      28             :       REAL, INTENT (IN) :: amat(3,3),bmat(3,3),taual(3,natd),tau(3,nop)
      29             :       REAL, INTENT (IN) :: force(3,ntypd)
      30             :       CHARACTER(LEN=20) :: label(natd)
      31             : 
      32           1 :       INTEGER :: iatom,iatom0,itype,ieq,ratom,isym,sym,i,true_atom,atom_map(natd)
      33             : 
      34           1 :       REAL :: pos(3,natd),rtaual(3),forcerot(3,3),forceval(3,natd)
      35             :       CHARACTER(len=20) :: string
      36             :       LOGICAL :: l_PHON
      37             : 
      38           1 :       l_PHON = .FALSE.
      39           1 :       OPEN (79,file='FORCES')
      40             :       IF (l_PHON) THEN
      41             :          OPEN (80,file='POSCAR')
      42             :       END IF
      43           1 :       OPEN(81,file='FORCES_SORT')
      44             : 
      45           1 :       WRITE (79,'(i1)') 1
      46           1 :       WRITE (79,'(i1,1x,a)') 1,'#'
      47           1 :       WRITE (81,'(i1)') 1
      48           1 :       WRITE (81,'(i1,1x,a)') 1,'#'
      49             :       IF (l_PHON) THEN
      50             :          WRITE (80,'(a)') "#insert lattice name"
      51             :          WRITE (80,'(f20.10)') -omtil*bohr_to_angstrom_const**3
      52             :          WRITE (80,FMT=800) amat(1,1:3)*bohr_to_angstrom_const
      53             :          WRITE (80,FMT=800) amat(2,1:3)*bohr_to_angstrom_const
      54             :          WRITE (80,FMT=800) amat(3,1:3)*bohr_to_angstrom_const
      55             :          WRITE (string,'(i3)') ntype
      56             :          WRITE (80,'('//string//'(i2,1x))') (neq(itype),itype=1,ntype)
      57             :          WRITE (80,'(a)') 'Direct'
      58             :       END IF
      59             : 
      60           1 :       iatom  = 0
      61           1 :       iatom0 = 1
      62           3 :       DO itype = 1,ntype
      63           5 :          DO ieq = 1,neq(itype)
      64           3 :             iatom = iatom+1
      65           3 :             true_atom = str2int(TRIM(label(iatom)))
      66           3 :             atom_map(true_atom) = iatom
      67          48 :             pos(:,iatom) = matmul(amat,taual(:,iatom))
      68             : 
      69             :             ratom = 0
      70           4 :             sym = 0
      71             : 
      72           4 :             DO isym = 1,nop
      73         112 :                rtaual(:)=matmul(mrot(:,:,isym),taual(:,iatom0))+tau(:,isym)
      74          13 :                IF(all(abs(modulo(rtaual-taual(:,iatom)+0.5,1d0)-0.5).lt.1d-10)) THEN
      75           3 :                   sym = isym
      76           3 :                   EXIT
      77             :                END IF
      78             :             END DO
      79             : 
      80           3 :             IF (sym.eq.0) THEN
      81           0 :                sym = 1
      82             :             END IF
      83             : 
      84         309 :             forcerot = matmul(amat,matmul(mrot(:,:,sym),bmat/tpi_const))
      85          48 :             forceval(:,iatom) = matmul(forcerot,force(:,itype))
      86             : 
      87           2 :             IF (l_PHON) THEN
      88             :                WRITE (79,FMT=790) forceval(1:3,iatom)*hartree_to_ev_const/bohr_to_angstrom_const
      89             :                WRITE (80,FMT=800) taual(1:3,iatom)
      90             :             ELSE
      91           3 :                WRITE (79,*) forceval(1:3,iatom), 'force'
      92             :             END IF
      93             :          END DO
      94           3 :          iatom0 = iatom0 + neq(itype)
      95             :       END DO
      96             : 
      97           4 :       DO iatom = 1, natd
      98           4 :          WRITE (81,*) forceval(1:3,atom_map(iatom)), 'force'
      99             :       END DO
     100             : 
     101             : 790   FORMAT (1x,3(1x,f20.10))
     102             : 800   FORMAT (1x,3(1x,f20.10))
     103             : 810   FORMAT (1x,a4,43x,3f14.9)
     104             : 
     105           1 :       CLOSE(79)
     106             :       IF (l_PHON) THEN
     107             :          CLOSE(80)
     108             :       END IF
     109           1 :       CLOSE(81)
     110             : 
     111           1 :    END SUBROUTINE rotate_forces
     112             : 
     113             : END MODULE m_rotate_forces

Generated by: LCOV version 1.14