LCOV - code coverage report
Current view: top level - src/78_effpot - m_harmonics_terms.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.0 % 212 159
Test Date: 2026-11-09 14:22:37 Functions: 80.0 % 10 8
Branches: 53.7 % 700 376

             Branch data     Line data    Source code
       1                 :             : !!****f* ABINIT/m_harmonics_terms
       2                 :             : !!
       3                 :             : !! NAME
       4                 :             : !! m_harmonics_term
       5                 :             : !!
       6                 :             : !! FUNCTION
       7                 :             : !! Module with datatype and tools for the harmonics terms
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (C) 2010-2026 ABINIT group (AM)
      11                 :             : !! This file is distributed under the terms of the
      12                 :             : !! GNU General Public Licence, see ~abinit/COPYING
      13                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      15                 :             : !!
      16                 :             : !! SOURCE
      17                 :             : 
      18                 :             : 
      19                 :             : #if defined HAVE_CONFIG_H
      20                 :             : #include "config.h"
      21                 :             : #endif
      22                 :             : 
      23                 :             : #include "abi_common.h"
      24                 :             : 
      25                 :             : module m_harmonics_terms
      26                 :             : 
      27                 :             :  use defs_basis
      28                 :             :  use m_errors
      29                 :             :  use m_abicore
      30                 :             :  use m_supercell,only: getPBCIndexes_supercell
      31                 :             :  use m_xmpi,only : xmpi_sum
      32                 :             :  use m_ifc
      33                 :             : 
      34                 :             :  implicit none
      35                 :             : 
      36                 :             :  public :: harmonics_terms_init
      37                 :             :  public :: harmonics_terms_free
      38                 :             :  public :: harmonics_terms_applySumRule
      39                 :             :  public :: harmonics_terms_evaluateIFC
      40                 :             :  public :: harmonics_terms_evaluateElastic
      41                 :             :  public :: harmonics_terms_setEffectiveCharges
      42                 :             :  public :: harmonics_terms_setDynmat
      43                 :             :  public :: harmonics_terms_setInternalStrain
      44                 :             : !!***
      45                 :             : 
      46                 :             : !!****t* m_harmonics_terms/harmonics_terms_type
      47                 :             : !! NAME
      48                 :             : !! harmonics_terms_type
      49                 :             : !!
      50                 :             : !! FUNCTION
      51                 :             : !! datatype for harmonic part of effective potential.
      52                 :             : !!
      53                 :             : !! SOURCE
      54                 :             : 
      55                 :             :  type, public :: harmonics_terms_type
      56                 :             : 
      57                 :             :    integer :: nqpt
      58                 :             : !   Number of qpoints
      59                 :             : 
      60                 :             :    real(dp) :: epsilon_inf(3,3)
      61                 :             : !   epsilon_inf(3,3)
      62                 :             : !   Dielectric tensor
      63                 :             : 
      64                 :             :    real(dp) :: elastic_constants(6,6)
      65                 :             : !   elastic_constant(6,6)
      66                 :             : !   Elastic tensor Hartree
      67                 :             : 
      68                 :             :    real(dp), allocatable :: strain_coupling(:,:,:)
      69                 :             : !   strain_coupling(6,3,natom)
      70                 :             : !   internal strain tensor
      71                 :             : 
      72                 :             :    real(dp), allocatable :: zeff(:,:,:)
      73                 :             : !   zeff(3,3,natom) Effective charges
      74                 :             : 
      75                 :             :    type(ifc_type) :: ifcs
      76                 :             : !   type with ifcs constants (short + ewald)
      77                 :             : !   also contains the number of cell and the indexes
      78                 :             : 
      79                 :             :    real(dp), allocatable :: qpoints(:,:)
      80                 :             : !   qph1l(3,nqpt)
      81                 :             : !   List of qpoints wavevectors
      82                 :             : 
      83                 :             :    real(dp), allocatable :: dynmat(:,:,:,:,:,:)
      84                 :             : !   dynmat(2,3,natom,3,natom,nqpt)
      85                 :             : !   dynamical matrix for each q points
      86                 :             : 
      87                 :             :    real(dp), allocatable :: phfrq(:,:)
      88                 :             : !   phfrq(3*natom,nqpt)
      89                 :             : !   array with all phonons frequencies for each q points in Hartree/cm
      90                 :             : 
      91                 :             :  end type harmonics_terms_type
      92                 :             : !!***
      93                 :             : 
      94                 :             : CONTAINS  !===========================================================================================
      95                 :             : 
      96                 :             : 
      97                 :             : !!****f* m_harmonics_terms/harmonics_terms_init
      98                 :             : !!
      99                 :             : !! NAME
     100                 :             : !! harmonics_terms_init
     101                 :             : !!
     102                 :             : !! FUNCTION
     103                 :             : !! Initialize harmonics_terms datatype
     104                 :             : !!
     105                 :             : !! INPUTS
     106                 :             : !! ifc<type(ifc_type)> = interatomic forces constants
     107                 :             : !! natom = number of atoms in primitive cell
     108                 :             : !! nrpt = number rpt (cell) in the ifc
     109                 :             : !! dynmat(2,3,natom,3,natom,3,nqpt) = optional, dynamical matricies for each q-point
     110                 :             : !! epsilon_inf(3,3) = optional, dielectric tensor
     111                 :             : !! elastic_constant(6,6) = optional, elastic constant
     112                 :             : !! strain_coupling(6,3,natom) = optional, internal strain coupling parameters
     113                 :             : !! nqpt = optional, number of q-points
     114                 :             : !! phfrq(3*natom,nqpt) = optional,phonons frequencies for each q points in Hartree/cm
     115                 :             : !! qpoints(3,nqpt) = list of qpoints wavevectors
     116                 :             : !! zeff(3,3,natom) = optional,effective charges
     117                 :             : !!
     118                 :             : !! OUTPUT
     119                 :             : !! harmonics_terms<type(harmonics_terms_type)> = harmonics_terms datatype to be initialized
     120                 :             : !!
     121                 :             : !! SOURCE
     122                 :             : 
     123   [ -  +  -  +  :         608 : subroutine harmonics_terms_init(harmonics_terms,ifcs,natom,nrpt,&
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             +  +  +  + ]
     124   [ -  +  -  -  :          76 : &                               dynmat,epsilon_inf,elastic_constants,strain_coupling,&
                   -  - ]
     125   [ -  +  -  + ]:          76 : &                               nqpt,phfrq,qpoints,zeff)
     126                 :             : 
     127                 :             :  implicit none
     128                 :             : 
     129                 :             : !Arguments ------------------------------------
     130                 :             : !scalars
     131                 :             :  integer, intent(in) :: natom,nrpt
     132                 :             : !arrays
     133                 :             :  type(ifc_type),intent(in) :: ifcs
     134                 :             :  type(harmonics_terms_type), intent(out) :: harmonics_terms
     135                 :             :  integer, optional,intent(in) :: nqpt
     136                 :             :  real(dp),optional,intent(in) :: epsilon_inf(3,3),dynmat(:,:,:,:,:,:)
     137                 :             :  real(dp),optional,intent(in) :: elastic_constants(6,6)
     138                 :             :  real(dp),optional,intent(in) :: strain_coupling(6,3,natom),zeff(3,3,natom)
     139                 :             :  real(dp),optional,intent(in) :: phfrq(:,:),qpoints(:,:)
     140                 :             : !Local variables-------------------------------
     141                 :             : !scalar
     142                 :             : !arrays
     143                 :             :  character(len=500) :: msg
     144                 :             : 
     145                 :             : ! *************************************************************************
     146                 :             : 
     147                 :          76 :  call harmonics_terms_free(harmonics_terms)
     148                 :             : 
     149                 :             : ! Do some Checks
     150         [ -  + ]:          76 :  if (natom < 1) then
     151                 :             :    write(msg, '(a,a,a,i10,a)' )&
     152                 :           0 : &   'The cell must have at least one atom.',ch10,&
     153                 :           0 : &   'The number of atom is  ',natom,'.'
     154                 :           0 :    ABI_BUG(msg)
     155                 :             :  end if
     156                 :             : 
     157         [ -  + ]:          76 :  if (nrpt < 1) then
     158                 :             :    write(msg, '(a,a,a,i10,a)' )&
     159                 :           0 : &   'The cell must have at least one rpt point.',ch10,&
     160                 :           0 : &   'The number of rpt points is  ',nrpt,'.'
     161                 :           0 :    ABI_BUG(msg)
     162                 :             :  end if
     163                 :             : 
     164         [ -  + ]:          76 :  if (nrpt /= ifcs%nrpt) then
     165                 :             :    write(msg, '(3a,i5,a,i5,a)' )&
     166                 :           0 : &   'nrpt must have the same dimension as ifcs.',ch10,&
     167                 :           0 : &   'The number of cell is  ',nrpt,' instead of ',ifcs%nrpt,'.'
     168                 :           0 :    ABI_BUG(msg)
     169                 :             :  end if
     170                 :             : 
     171   [ +  -  -  -  :          76 :  if(present(nqpt).and.(.not.present(dynmat).or.&
                   -  - ]
     172                 :             : &                      .not.present(qpoints)   .or.&
     173                 :             : &                      .not.present(phfrq)))then
     174                 :             :    write(msg, '(a)' )&
     175                 :           0 : &   'nqpt is specified but dynamt,qpoints or phfrq are not.'
     176                 :           0 :    ABI_BUG(msg)
     177                 :             :  end if
     178                 :             : 
     179   [ +  -  -  + ]:          76 :  if(.not.present(nqpt).and.(present(dynmat).or.&
     180                 :             : &                      present(qpoints)   .or.&
     181                 :             : &                      present(phfrq)))then
     182                 :             :    write(msg, '(a)' )&
     183                 :           0 : &   ' dynamt,qpoints or phfrq are specified but nqpt is not.'
     184                 :           0 :    ABI_BUG(msg)
     185                 :             :  end if
     186                 :             : 
     187                 :             : !Set number of cell
     188                 :          76 :  harmonics_terms%ifcs%nrpt = nrpt
     189                 :             : 
     190                 :             : !Allocation of total ifc
     191   [ -  +  +  -  :         456 :  ABI_MALLOC(harmonics_terms%ifcs%atmfrc,(3,natom,3,natom,nrpt))
          +  -  -  +  +  
          -  -  +  +  -  
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     192   [ +  +  +  +  :      922666 :  harmonics_terms%ifcs%atmfrc(:,:,:,:,:) = ifcs%atmfrc(:,:,:,:,:)
          +  +  +  +  +  
                      + ]
     193                 :             : 
     194                 :             : !Allocation of ewald part of ifc
     195   [ -  +  +  -  :         304 :  ABI_MALLOC(harmonics_terms%ifcs%ewald_atmfrc,(3,natom,3,natom,nrpt))
          -  +  +  -  -  
          +  +  -  -  +  
             -  +  -  + ]
     196   [ +  +  +  +  :      922666 :  harmonics_terms%ifcs%ewald_atmfrc(:,:,:,:,:) = ifcs%ewald_atmfrc(:,:,:,:,:)
          +  +  +  +  +  
                      + ]
     197                 :             : 
     198                 :             : !Allocation of short range part of ifc
     199   [ -  +  +  -  :         304 :  ABI_MALLOC(harmonics_terms%ifcs%short_atmfrc,(3,natom,3,natom,nrpt))
          -  +  +  -  -  
          +  +  -  -  +  
             -  +  -  + ]
     200   [ +  +  +  +  :      922666 :  harmonics_terms%ifcs%short_atmfrc(:,:,:,:,:) = ifcs%short_atmfrc(:,:,:,:,:)
          +  +  +  +  +  
                      + ]
     201                 :             : 
     202                 :             : !Allocation of cell of ifc
     203   [ -  +  +  -  :         228 :  ABI_MALLOC(harmonics_terms%ifcs%cell,(3,nrpt))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     204   [ +  +  +  + ]:        8772 :  harmonics_terms%ifcs%cell(:,:) = ifcs%cell(:,:)
     205                 :             : 
     206                 :             : !Allocation of the dynamical matrix
     207                 :          76 :  harmonics_terms%nqpt = 0
     208   [ -  +  -  - ]:          76 :  if(present(nqpt).and.present(dynmat).and.present(qpoints).and.present(phfrq))then
     209                 :             :    call harmonics_terms_setDynmat(dynmat,harmonics_terms,natom,nqpt,&
     210                 :           0 : &                                 harmonics_terms%phfrq,harmonics_terms%qpoints)
     211                 :             :  end if
     212                 :             : 
     213                 :             : !Allocation of the elastic constants
     214   [ +  +  +  + ]:        3268 :  harmonics_terms%elastic_constants = zero
     215         [ -  + ]:          76 :  if (present(elastic_constants)) then
     216   [ #  #  #  # ]:           0 :    harmonics_terms%elastic_constants = elastic_constants
     217                 :             :  end if
     218                 :             : 
     219                 :             : !Allication of the dielectric tensor
     220   [ +  +  +  + ]:         988 :  harmonics_terms%epsilon_inf = zero
     221         [ -  + ]:          76 :  if (present(epsilon_inf)) then
     222   [ #  #  #  # ]:           0 :    harmonics_terms%epsilon_inf = epsilon_inf
     223                 :             :  end if
     224                 :             : 
     225                 :             : !Allocation of Effective charges array
     226   [ -  +  +  -  :         228 :  ABI_MALLOC(harmonics_terms%zeff,(3,3,natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     227   [ +  +  +  +  :        5198 :  harmonics_terms%zeff = zero
                   +  + ]
     228         [ -  + ]:          76 :  if (present(zeff)) then
     229                 :           0 :    call harmonics_terms_setEffectiveCharges(harmonics_terms,natom,zeff)
     230   [ #  #  #  #  :           0 :    harmonics_terms%zeff = zeff
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     231                 :             :  end if
     232                 :             : 
     233                 :             : !Allocation of internal strain tensor
     234   [ -  +  +  -  :         228 :  ABI_MALLOC(harmonics_terms%strain_coupling,(6,3,natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     235   [ +  +  +  +  :        8744 :  harmonics_terms%strain_coupling = zero
                   +  + ]
     236         [ -  + ]:          76 :  if (present(strain_coupling)) then
     237                 :           0 :    call harmonics_terms_setInternalStrain(harmonics_terms,natom,strain_coupling)
     238                 :             :  end if
     239                 :             : 
     240   [ -  +  -  + ]:          76 : end subroutine harmonics_terms_init
     241                 :             : !!***
     242                 :             : 
     243                 :             : 
     244                 :             : !****f* m_harmonics_terms/harmonics_terms_free
     245                 :             : !!
     246                 :             : !! NAME
     247                 :             : !! harmonics_terms_free
     248                 :             : !!
     249                 :             : !! FUNCTION
     250                 :             : !! deallocate all dynamic memory for this harmonic datatype
     251                 :             : !!
     252                 :             : !! INPUTS
     253                 :             : !! harmonics_terms<type(harmonics_terms_type)> = harmonics_terms datatype to be free
     254                 :             : !!
     255                 :             : !! OUTPUT
     256                 :             : !! harmonics_terms<type(harmonics_terms_type)> = harmonics_terms datatype to be free
     257                 :             : !!
     258                 :             : !! SOURCE
     259                 :             : 
     260                 :         610 : subroutine harmonics_terms_free(harmonics_terms)
     261                 :             : 
     262                 :             :   implicit none
     263                 :             : 
     264                 :             : !Arguments ------------------------------------
     265                 :             : !scalars
     266                 :             : !array
     267                 :             :   type(harmonics_terms_type), intent(inout) :: harmonics_terms
     268                 :             : !Local variables-------------------------------
     269                 :             : !scalars
     270                 :             : !array
     271                 :             : 
     272                 :             : ! *************************************************************************
     273                 :             : 
     274                 :         610 :   harmonics_terms%nqpt = 0
     275   [ +  +  +  + ]:       26230 :   harmonics_terms%elastic_constants = zero
     276   [ +  +  +  + ]:        7930 :   harmonics_terms%epsilon_inf       = zero
     277                 :             : 
     278         [ +  + ]:         610 :   if(allocated(harmonics_terms%zeff))then
     279   [ +  +  +  +  :        7203 :     harmonics_terms%zeff=zero
                   +  + ]
     280                 :         105 :     ABI_FREE(harmonics_terms%zeff)
     281                 :             :   end if
     282                 :             : 
     283         [ +  + ]:         610 :   if(allocated(harmonics_terms%strain_coupling)) then
     284   [ +  +  +  +  :       12117 :     harmonics_terms%strain_coupling=zero
                   +  + ]
     285                 :         105 :     ABI_FREE(harmonics_terms%strain_coupling)
     286                 :             :   end if
     287                 :             : 
     288         [ +  + ]:         610 :   if(allocated(harmonics_terms%dynmat))then
     289   [ +  +  +  +  :      185742 :     harmonics_terms%dynmat=zero
          +  +  +  +  +  
                +  +  + ]
     290                 :         105 :     ABI_FREE(harmonics_terms%dynmat)
     291                 :             :   end if
     292                 :             : 
     293         [ +  + ]:         610 :   if(allocated(harmonics_terms%phfrq))then
     294   [ +  +  +  + ]:        3904 :     harmonics_terms%phfrq=zero
     295                 :         105 :     ABI_FREE(harmonics_terms%phfrq)
     296                 :             :   end if
     297                 :             : 
     298         [ +  + ]:         610 :   if(allocated(harmonics_terms%qpoints))then
     299   [ +  +  +  + ]:        1165 :     harmonics_terms%qpoints=zero
     300                 :         105 :     ABI_FREE(harmonics_terms%qpoints)
     301                 :             :   end if
     302                 :             : 
     303                 :         610 :   call harmonics_terms%ifcs%free()
     304                 :             : 
     305                 :         610 : end subroutine harmonics_terms_free
     306                 :             : !!***
     307                 :             : 
     308                 :             : !****f* m_harmonics_terms/harmonics_terms_setInternalStrain
     309                 :             : !!
     310                 :             : !! NAME
     311                 :             : !! harmonics_terms_setInternalStrain
     312                 :             : !!
     313                 :             : !! FUNCTION
     314                 :             : !! Set the internal strain to the harmonics_terms
     315                 :             : !!
     316                 :             : !! INPUTS
     317                 :             : !! natom = number of atoms
     318                 :             : !! strain_coupling(6,3,natom) = internal strain coupling parameters
     319                 :             : !!
     320                 :             : !! OUTPUT
     321                 :             : !! harmonics_terms<type(harmonics_terms_type)> = harmonics_terms datatype
     322                 :             : !!
     323                 :             : !! SOURCE
     324                 :             : 
     325         [ -  + ]:          76 : subroutine harmonics_terms_setInternalStrain(harmonics_terms,natom,strain_coupling)
     326                 :             : 
     327                 :             :   implicit none
     328                 :             : 
     329                 :             : !Arguments ------------------------------------
     330                 :             : !scalars
     331                 :             :   integer,intent(in) :: natom
     332                 :             : !array
     333                 :             :   real(dp),intent(in) :: strain_coupling(:,:,:)
     334                 :             :   type(harmonics_terms_type), intent(inout) :: harmonics_terms
     335                 :             : !Local variables-------------------------------
     336                 :             : !scalars
     337                 :             : !array
     338                 :             :   character(len=500) :: msg
     339                 :             : 
     340                 :             : ! *************************************************************************
     341                 :             : 
     342                 :             : ! 0-Checks inputs
     343         [ -  + ]:          76 :   if(natom /= size(strain_coupling,3)) then
     344                 :             :     write(msg, '(a)' )&
     345                 :           0 : &        ' natom has not the same size strain_coupling array. '
     346                 :           0 :     ABI_BUG(msg)
     347                 :             :   end if
     348                 :             : 
     349                 :             : ! 1-deallocate old array
     350         [ +  - ]:          76 :   if(allocated(harmonics_terms%strain_coupling))then
     351                 :          76 :     ABI_FREE(harmonics_terms%strain_coupling)
     352                 :             :   end if
     353                 :             : 
     354                 :             : ! 2-allocate and copy the new array
     355   [ -  +  +  -  :         228 :   ABI_MALLOC(harmonics_terms%strain_coupling,(6,3,natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     356   [ +  +  +  +  :        8744 :   harmonics_terms%strain_coupling(:,:,:) = strain_coupling(:,:,:)
                   +  + ]
     357                 :             : 
     358                 :          76 : end subroutine harmonics_terms_setInternalStrain
     359                 :             : !!***
     360                 :             : 
     361                 :             : 
     362                 :             : !****f* m_harmonics_terms/harmonics_terms_setEffectiveCharges
     363                 :             : !!
     364                 :             : !! NAME
     365                 :             : !! harmonics_terms_setEffectiveCharges
     366                 :             : !!
     367                 :             : !! FUNCTION
     368                 :             : !! Set the effectives charges to the harmonics_terms
     369                 :             : !!
     370                 :             : !! INPUTS
     371                 :             : !! natom = number of atoms
     372                 :             : !! zeff(3,natom) = effective charges
     373                 :             : !!
     374                 :             : !! OUTPUT
     375                 :             : !! harmonics_terms<type(harmonics_terms_type)> = harmonics_terms datatype
     376                 :             : !!
     377                 :             : !! SOURCE
     378                 :             : 
     379         [ -  + ]:          76 : subroutine harmonics_terms_setEffectiveCharges(harmonics_terms,natom,zeff)
     380                 :             : 
     381                 :             :   implicit none
     382                 :             : 
     383                 :             : !Arguments ------------------------------------
     384                 :             : !scalars
     385                 :             :   integer,intent(in) :: natom
     386                 :             : !array
     387                 :             :   real(dp),intent(in) :: zeff(:,:,:)
     388                 :             :   type(harmonics_terms_type), intent(inout) :: harmonics_terms
     389                 :             : !Local variables-------------------------------
     390                 :             : !scalars
     391                 :             : !array
     392                 :             :   character(len=500) :: msg
     393                 :             : ! *************************************************************************
     394                 :             : 
     395                 :             : ! 0-Checks inputs
     396         [ -  + ]:          76 :     if(natom /= size(zeff,3)) then
     397                 :             :     write(msg, '(a)' )&
     398                 :           0 : &        ' natom has not the same size zeff array. '
     399                 :           0 :     ABI_BUG(msg)
     400                 :             :   end if
     401                 :             : 
     402                 :             : ! 1-deallocate old array
     403         [ +  - ]:          76 :   if(allocated(harmonics_terms%zeff))then
     404                 :          76 :     ABI_FREE(harmonics_terms%zeff)
     405                 :             :   end if
     406                 :             : 
     407                 :             : ! 2-allocate and copy the new array
     408   [ -  +  +  -  :         228 :   ABI_MALLOC(harmonics_terms%zeff,(3,3,natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     409   [ +  +  +  +  :        5198 :   harmonics_terms%zeff(:,:,:) = zeff(:,:,:)
                   +  + ]
     410                 :             : 
     411                 :             : 
     412                 :          76 : end subroutine harmonics_terms_setEffectiveCharges
     413                 :             : !!***
     414                 :             : 
     415                 :             : !****f* m_harmonics_terms/harmonics_terms_setDynmat
     416                 :             : !!
     417                 :             : !! NAME
     418                 :             : !! harmonics_terms_setDynmat
     419                 :             : !!
     420                 :             : !! FUNCTION
     421                 :             : !! Set the dynamical matricies to the harmonics_terms
     422                 :             : !!
     423                 :             : !! INPUTS
     424                 :             : !! natom = number of atoms
     425                 :             : !! nqpt  = number of qpoints
     426                 :             : !! dynmat(2,3,natom,3,natom,nqpt) = dynamical matrix in cartesian coordinates
     427                 :             : !! phfrq(3*natom,nqpt) = frequency in hartree
     428                 :             : !! qpoints(3,nqpt) = list of qpoints
     429                 :             : !!
     430                 :             : !! OUTPUT
     431                 :             : !! harmonics_terms<type(harmonics_terms_type)> = harmonics_terms datatype
     432                 :             : !!
     433                 :             : !! SOURCE
     434                 :             : 
     435   [ -  +  -  +  :          76 : subroutine harmonics_terms_setDynmat(dynmat,harmonics_terms,natom,nqpt,phfrq,qpoints)
                   -  + ]
     436                 :             : 
     437                 :             :   implicit none
     438                 :             : 
     439                 :             : !Arguments ------------------------------------
     440                 :             : !scalars
     441                 :             :   integer,intent(in) :: natom,nqpt
     442                 :             : !array
     443                 :             :   real(dp),intent(in) :: dynmat(:,:,:,:,:,:)
     444                 :             :   real(dp),intent(in) :: qpoints(:,:)
     445                 :             :   real(dp),intent(in) :: phfrq(:,:)
     446                 :             :   type(harmonics_terms_type), intent(inout) :: harmonics_terms
     447                 :             : !Local variables-------------------------------
     448                 :             : !scalars
     449                 :             : !array
     450                 :             :   character(len=500) :: msg
     451                 :             : ! *************************************************************************
     452                 :             : 
     453                 :             : ! 0-Checks inputs
     454   [ +  -  -  + ]:          76 :     if((natom /= size(dynmat,3)).or.(natom /= size(dynmat,5))) then
     455                 :             :     write(msg, '(a)' )&
     456                 :           0 : &        ' natom has not the same size dynmat array. '
     457                 :           0 :     ABI_BUG(msg)
     458                 :             :   end if
     459                 :             : 
     460         [ -  + ]:          76 :   if (nqpt /= size(dynmat,6))then
     461                 :             :     write(msg, '(a)' )&
     462                 :           0 : &        ' nqpt has not the same size dynmat array. '
     463                 :           0 :     ABI_BUG(msg)
     464                 :             :   end if
     465                 :             : 
     466         [ -  + ]:          76 :   if (nqpt /= size(qpoints,2))then
     467                 :             :     write(msg, '(a)' )&
     468                 :           0 : &        ' nqpt has not the same size qpoints array. '
     469                 :           0 :     ABI_BUG(msg)
     470                 :             :   end if
     471                 :             : 
     472         [ -  + ]:          76 :   if (nqpt /= size(phfrq,2))then
     473                 :             :     write(msg, '(a)' )&
     474                 :           0 : &        ' nqpt has not the same size phfrq array. '
     475                 :           0 :     ABI_BUG(msg)
     476                 :             :   end if
     477                 :             : 
     478                 :             : ! 1-deallocate old array
     479         [ -  + ]:          76 :   if(allocated(harmonics_terms%dynmat))then
     480                 :           0 :     ABI_FREE(harmonics_terms%dynmat)
     481                 :             :   end if
     482                 :             : 
     483         [ -  + ]:          76 :   if(allocated(harmonics_terms%phfrq))then
     484                 :           0 :     ABI_FREE(harmonics_terms%phfrq)
     485                 :             :   end if
     486                 :             : 
     487         [ -  + ]:          76 :   if(allocated(harmonics_terms%qpoints))then
     488                 :           0 :     ABI_FREE(harmonics_terms%qpoints)
     489                 :             :   end if
     490                 :             : 
     491                 :             : ! 2-allocate and copy the new array
     492                 :          76 :   harmonics_terms%nqpt = nqpt
     493                 :             : 
     494   [ -  +  +  -  :         456 :   ABI_MALLOC(harmonics_terms%dynmat,(2,3,natom,3,natom,nqpt))
          +  -  -  +  +  
          -  +  +  +  -  
          +  -  +  +  -  
             +  -  +  -  
                      + ]
     495   [ +  +  +  +  :      126404 :   harmonics_terms%dynmat(:,:,:,:,:,:) = dynmat(:,:,:,:,:,:)
          +  +  +  +  +  
                +  +  + ]
     496                 :             : 
     497   [ +  -  -  +  :         304 :   ABI_MALLOC(harmonics_terms%phfrq,(3*natom,nqpt))
          +  -  +  +  +  
          -  +  -  +  +  
          -  +  -  +  -  
                      + ]
     498   [ +  +  +  + ]:        2662 :   harmonics_terms%phfrq(:,:) = phfrq(:,:)
     499                 :             : 
     500   [ +  +  +  -  :         228 :   ABI_MALLOC(harmonics_terms%qpoints,(3,nqpt))
          +  -  +  +  -  
             +  -  +  -  
                      + ]
     501   [ +  +  +  + ]:         796 :   harmonics_terms%qpoints(:,:) = qpoints(:,:)
     502                 :             : 
     503                 :          76 : end subroutine harmonics_terms_setDynmat
     504                 :             : !!***
     505                 :             : !!****f* m_harmonics_terms/harmonics_terms_evaluateIFC
     506                 :             : !! NAME
     507                 :             : !!  harmonics_terms_evaluateIFC
     508                 :             : !!
     509                 :             : !! FUNCTION
     510                 :             : !!  This fonction compute the contribution of the ifc harmonic part of
     511                 :             : !!  the energy and forces.
     512                 :             : !!
     513                 :             : !! INPUTS
     514                 :             : !!  atmfrc(3,natom_uc,3,natom_uc,nrpt) = atomic force constants
     515                 :             : !!  disp(3,natom_sc) = atomics displacement between configuration and the reference
     516                 :             : !!  ncell = total number of cell to treat
     517                 :             : !!  nrpt  = total number of rpt to treat
     518                 :             : !!  natom_sc = number of atoms in the supercell
     519                 :             : !!  natom_uc = number of atoms in the unit cell
     520                 :             : !!  nrpt  = number of rpt
     521                 :             : !!  atmrpt_index(nrpt,cell) = For each cell in the supercell and each rpt,
     522                 :             : !!                            give the index of the first atoms in the rpt cell
     523                 :             : !!  rpt(nrpt) = index of rpt in  atmfrc (6th dimension)
     524                 :             : !!  index_cells(3,ncell) = indexes of the cells into  supercell (-1 -1 -1 ,...,1 1 1)
     525                 :             : !!  comm=MPI communicator
     526                 :             : !!
     527                 :             : !! OUTPUT
     528                 :             : !!   energy = contribution of the ifc to the energy
     529                 :             : !!   fcart(3,natom) = contribution of the ifc to the forces
     530                 :             : !!
     531                 :             : !! PARENT
     532                 :             : !!   effective_potential_evaluate
     533                 :             : !!
     534                 :             : !! SOURCE
     535                 :             : 
     536                 :       27038 : subroutine harmonics_terms_evaluateIFC(atmfrc,disp,energy,fcart,natom_sc,natom_uc,&
     537                 :       13519 : &                                      ncell,nrpt,atmrpt_index,index_cells,sc_size,rpt,comm)
     538                 :             : 
     539                 :             :  implicit none
     540                 :             : 
     541                 :             : !Arguments -------------------------------
     542                 :             : ! scalars
     543                 :             :   real(dp),intent(out) :: energy
     544                 :             :   integer,intent(in) :: natom_uc,natom_sc,ncell,nrpt
     545                 :             :   integer,intent(in) :: comm
     546                 :             : ! array
     547                 :             :   integer,intent(in) :: sc_size(3),atmrpt_index(nrpt,ncell)
     548                 :             :   integer,intent(in) ::  index_cells(4,ncell),rpt(nrpt)
     549                 :             :   real(dp),intent(in) :: atmfrc(3,natom_uc,3,natom_uc,nrpt)
     550                 :             :   real(dp),intent(in) :: disp(3,natom_sc)
     551                 :             :   real(dp),intent(out) :: fcart(3,natom_sc)
     552                 :             : 
     553                 :             : !Local variables-------------------------------
     554                 :             : ! scalar
     555                 :             :   integer :: i1,i2,i3,ia,ib,icell,ierr,irpt,irpt_tmp,ii,jj,kk,ll
     556                 :             :   integer :: mu,nu
     557                 :             :   real(dp):: disp1,disp2,ifc,tmp_etot1,tmp_etot2
     558                 :             : !Variables for separation of short and dipdip ifc contribution
     559                 :             :  !real(dp):: short_ifc,ewald_ifc
     560                 :             :  !real(dp):: tmp_ewald1,tmp_ewald2,tmp_short1,tmp_short2
     561                 :             :   ! array
     562                 :             :   character(500) :: msg
     563                 :             : 
     564                 :             : ! *************************************************************************
     565                 :             : 
     566   [ +  +  +  -  :       54076 :   if (any(sc_size <= 0)) then
                   -  + ]
     567                 :           0 :     write(msg,'(a,a)')' sc_size can not be inferior or equal to zero'
     568                 :           0 :     ABI_ERROR(msg)
     569                 :             :   end if
     570                 :             : 
     571                 :             : ! Initialisation of variables
     572                 :       13519 :   energy   = zero
     573   [ +  +  +  + ]:    36076719 :   fcart(:,:) = zero
     574                 :             : 
     575         [ +  + ]:     1786383 :   do icell = 1,ncell
     576                 :     1772864 :     i1 = index_cells(1,icell)
     577                 :     1772864 :     i2 = index_cells(2,icell)
     578                 :     1772864 :     i3 = index_cells(3,icell)
     579                 :             : !   index of the first atom in the current cell
     580                 :     1772864 :     ii = index_cells(4,icell)
     581         [ +  + ]:   377817063 :     do irpt_tmp = 1,nrpt
     582                 :   376030680 :       irpt = rpt(irpt_tmp)
     583                 :             : !     index of the first atom in the irpt cell
     584                 :   376030680 :       jj = atmrpt_index(irpt_tmp,icell)
     585                 :             : !     Loop over the atom in the cell
     586         [ +  + ]:  2264040144 :       do ib = 1, natom_uc
     587                 :  1886236600 :         ll = jj + ib
     588         [ +  + ]:  7920977080 :         do nu=1,3
     589                 :  5658709800 :           disp2 = disp(nu,ll)
     590         [ +  + ]: 36206405800 :           do ia = 1, natom_uc
     591                 : 28661459400 :             kk = ii + ia
     592         [ +  + ]: >12030*10^7 :             do mu=1,3
     593                 : 85984378200 :               disp1 = disp(mu,kk)
     594                 : 85984378200 :               ifc = atmfrc(mu,ia,nu,ib,irpt)
     595                 :             : 
     596                 :             : !              if(abs(ifc) > tol10)then
     597                 : 85984378200 :                 tmp_etot1  = disp2 * ifc
     598                 :             : !               accumule energy
     599                 : 85984378200 :                 tmp_etot2  = disp1*tmp_etot1
     600                 : 85984378200 :                 energy =  energy + tmp_etot2
     601                 :             : !               accumule forces
     602                 : >11464*10^7 :                 fcart(mu,kk) = fcart(mu,kk) + tmp_etot1
     603                 :             : !              end if
     604                 :             :             end do
     605                 :             :           end do
     606                 :             :         end do
     607                 :             :       end do
     608                 :             :     end do
     609                 :             :   end do
     610                 :             : 
     611                 :       13519 :   energy = half * energy
     612                 :             : ! MPI_SUM
     613                 :       13519 :   call xmpi_sum(energy, comm, ierr)
     614                 :       13519 :   call xmpi_sum(fcart , comm, ierr)
     615                 :             : 
     616                 :       13519 : end subroutine harmonics_terms_evaluateIFC
     617                 :             : !!***
     618                 :             : 
     619                 :             : !!****f* m_harmonics_terms/harmonics_terms_evaluateElastic
     620                 :             : !! NAME
     621                 :             : !!  harmonics_terms_evaluateElastic
     622                 :             : !!
     623                 :             : !! FUNCTION
     624                 :             : !! Compute the energy, forces and stresses related to the application of strain
     625                 :             : !!
     626                 :             : !! INPUTS
     627                 :             : !!  elastic_constants(6,6) = elastic constants in Hartree
     628                 :             : !!  disp(3,natom_sc) = atomics displacement between configuration and the reference
     629                 :             : !!  natom = number of atoms in the supercell
     630                 :             : !!  natom_uc = number of atoms in the unit cell
     631                 :             : !!  ncell = total number of cell
     632                 :             : !!  strain_coupling(6,3,natom) = internal strain coupling parameters
     633                 :             : !!  strain(6) = strain between configuration and the reference
     634                 :             : !!
     635                 :             : !! OUTPUT
     636                 :             : !!   energy = contribution to the energy
     637                 :             : !!   fcart(3,natom) = contribution to the forces
     638                 :             : !!   strten(6) = contribution to the stress tensor
     639                 :             : !!
     640                 :             : !! SOURCE
     641                 :             : !!
     642                 :       13519 : subroutine harmonics_terms_evaluateElastic(elastic_constants,disp,energy,fcart,natom,natom_uc,ncell,&
     643                 :       13519 : &                                          strain_coupling,strten,strain)
     644                 :             : 
     645                 :             :  real(dp),intent(out):: energy
     646                 :             :  integer, intent(in) :: natom,natom_uc,ncell
     647                 :             : ! array
     648                 :             :  real(dp),intent(in) :: elastic_constants(6,6),strain_coupling(6,3,natom)
     649                 :             :  real(dp),intent(out):: strten(6)
     650                 :             :  real(dp),intent(out):: fcart(3,natom)
     651                 :             :  real(dp),intent(in) :: disp(3,natom)
     652                 :             :  real(dp),intent(in) :: strain(6)
     653                 :             : 
     654                 :             :  !Local variables-------------------------------
     655                 :             : ! scalar
     656                 :             :  integer :: ia,ii,mu,alpha,beta
     657                 :             :  real(dp):: cij
     658                 :             : ! array
     659                 :             : ! *************************************************************************
     660                 :             : 
     661                 :       13519 :  energy = zero
     662   [ +  +  +  + ]:    36076719 :  fcart = zero
     663                 :       13519 :  strten = zero
     664                 :             : 
     665                 :             : ! write(*,*) "----- STRAIN -----"
     666                 :             : ! write(*,*) strain
     667                 :             : 
     668                 :             : !1- Part due to elastic constants
     669         [ +  + ]:       94633 :  do alpha=1,6
     670         [ +  + ]:      581317 :    do beta=1,6
     671                 :             : !     write(*,*) "--- cij --- alpha: ", alpha, " beta: ", beta
     672                 :      486684 :      cij = ncell*elastic_constants(alpha,beta)
     673                 :             : !     write(*,*) cij
     674                 :      486684 :      energy = energy + half*cij*strain(alpha)*strain(beta)
     675                 :      567798 :      strten(alpha) = strten(alpha) + cij*strain(beta)
     676                 :             :    end do
     677                 :             : !   write(*,*) "strten(",alpha,"): ", strten(alpha)
     678                 :             :  end do
     679                 :             : 
     680                 :             : !2-Part due to the internal strain coupling parameters
     681                 :             :  ii = 1
     682         [ +  + ]:     9029319 :  do ia = 1,natom
     683         [ +  + ]:    36063200 :    do mu = 1,3
     684         [ +  + ]:   198347600 :      do alpha=1,6
     685                 :   162284400 :        cij = strain_coupling(alpha,mu,ii)
     686                 :             : !      Accumulte for this atom
     687                 :   162284400 :        energy = energy + half*cij*strain(alpha)*disp(mu,ia)
     688                 :   162284400 :        fcart(mu,ia)  = fcart(mu,ia)  + half*cij*strain(alpha)
     689                 :   189331800 :        strten(alpha) = strten(alpha) + half*cij*disp(mu,ia)
     690                 :             :      end do
     691                 :             :    end do
     692                 :     9015800 :    ii = ii +1
     693                 :             : !  Reset to 1 if the number of atoms is superior than in the initial cell
     694         [ +  + ]:     9029319 :    if(ii==natom_uc+1) ii = 1
     695                 :             :  end do
     696                 :             : 
     697                 :             : ! write(*,*) "--- STRTEN at the end --- "
     698                 :             : ! write(*,*) strten(:)
     699                 :             : 
     700                 :       13519 : end subroutine  harmonics_terms_evaluateElastic
     701                 :             : !!***
     702                 :             : 
     703                 :             : !****f* m_harmonics_terms/harmonics_terms_applySumRule
     704                 :             : !!
     705                 :             : !! NAME
     706                 :             : !! harmonics_terms_applySumRule
     707                 :             : !!
     708                 :             : !! FUNCTION
     709                 :             : !! Apply the acoustic sum rule on the inter-atomic force constants
     710                 :             : !!
     711                 :             : !! INPUTS
     712                 :             : !! ifc<type(ifc_type)> = interatomic forces constants
     713                 :             : !! asr   = acoustic sum rule option (see anaddb help)
     714                 :             : !! natom = number of atoms
     715                 :             : !! option = optional if |no present asr is done on total ifc
     716                 :             : !!                       |present and 1 asr is done on short part
     717                 :             : !!                       |present and 2 asr is done on ewald part
     718                 :             : !!
     719                 :             : !! OUTPUT
     720                 :             : !! ifc<type(ifc_type)> = interatomic forces constants
     721                 :             : !!
     722                 :             : !! SOURCE
     723                 :             : 
     724                 :          67 : subroutine harmonics_terms_applySumRule(asr,ifc,natom,option)
     725                 :             : 
     726                 :             :   implicit none
     727                 :             : 
     728                 :             : !Arguments ------------------------------------
     729                 :             : !scalars
     730                 :             :  integer,intent(in) :: asr
     731                 :             :  integer,intent(in) :: natom
     732                 :             :  integer,optional,intent(in) :: option
     733                 :             : !array
     734                 :             :  type(ifc_type),target,intent(inout) :: ifc
     735                 :             : !Local variables-------------------------------
     736                 :             : !scalar
     737                 :             :  integer :: ia,ib,irpt,irpt_ref
     738                 :             :  integer :: mu,nu
     739                 :             :  real(dp) :: sum
     740                 :             :  character(500) :: msg
     741                 :             : !array
     742                 :          67 :  real(dp),pointer :: atmfrc(:,:,:,:,:)
     743                 :             : ! *************************************************************************
     744                 :             : 
     745                 :          67 :  irpt_ref = 0
     746                 :             : ! Found the cell of reference
     747         [ +  + ]:        6494 :  do irpt = 1,ifc%nrpt
     748                 :             :    if(ifc%cell(1,irpt)==0.and.&
     749   [ +  +  +  +  :        6427 : &     ifc%cell(2,irpt)==0.and.&
                   +  + ]
     750                 :          67 : &     ifc%cell(3,irpt)==0) then
     751                 :        6427 :      irpt_ref = irpt
     752                 :             :      cycle
     753                 :             :    end if
     754                 :             :  end do
     755                 :             : 
     756         [ -  + ]:          67 :  if (irpt_ref<=0) then
     757                 :           0 :    write(msg,'(a,a)')' Unable to find the cell of reference in IFC'
     758                 :           0 :    ABI_ERROR(msg)
     759                 :             :  end if
     760                 :             : 
     761                 :          67 :  atmfrc => ifc%atmfrc
     762         [ -  + ]:          67 :  if (present(option)) then
     763         [ #  # ]:           0 :    if (option == 1) then
     764                 :           0 :      nullify(atmfrc)
     765                 :           0 :      atmfrc => ifc%short_atmfrc
     766                 :           0 :      write(msg,'(3a)') ch10," Impose acoustic sum rule on short range"
     767         [ #  # ]:           0 :    else if (option == 2) then
     768                 :           0 :      nullify(atmfrc)
     769                 :           0 :      atmfrc => ifc%ewald_atmfrc
     770                 :           0 :      write(msg,'(3a)') ch10," Impose acoustic sum rule on long range"
     771                 :             :    end if
     772                 :             :  else
     773                 :          67 :    write(msg,'(3a)') ch10," Impose acoustic sum rule on total ifc"
     774                 :             :  end if
     775                 :          67 :  call wrtout(ab_out,msg,'COLL')
     776                 :          67 :  call wrtout(std_out,msg,'COLL')
     777                 :             : 
     778                 :             : !impose acoustic sum rule:
     779         [ +  + ]:         268 :  do mu=1,3
     780         [ +  + ]:         871 :    do nu=1,3
     781         [ +  + ]:        4008 :      do ia=1,natom
     782                 :             :        sum=zero
     783         [ +  + ]:       26460 :        do ib=1,natom
     784                 :             : !      Get the sum of interatomic forces acting on the atom ia,
     785                 :             : !      either in a symmetrical manner, or an unsymmetrical one.
     786         [ -  + ]:       26460 :          if(asr==1)then
     787         [ #  # ]:           0 :            do irpt=1, ifc%nrpt
     788                 :           0 :              sum=sum+atmfrc(mu,ia,nu,ib,irpt)
     789                 :             :            end do
     790         [ +  - ]:       23256 :          else if(asr==2)then
     791         [ +  + ]:     1842957 :            do irpt=1, ifc%nrpt
     792                 :             :               sum=sum+&
     793                 :             : &                 (atmfrc(mu,ia,nu,ib,irpt)+&
     794                 :     1842957 : &                  atmfrc(nu,ia,mu,ib,irpt))/2
     795                 :             :             end do
     796                 :             :           end if
     797                 :             :         end do
     798                 :             : 
     799                 :             : !      Correct the self-interaction in order to fulfill the ASR
     800                 :             :         atmfrc(mu,ia,nu,ia,irpt_ref)=&
     801                 :        3204 : &       atmfrc(mu,ia,nu,ia,irpt_ref)-sum
     802         [ +  - ]:        3807 :         if(asr==2)then
     803                 :             :           atmfrc(nu,ia,mu,ia,irpt_ref)=&
     804                 :        3204 : &         atmfrc(mu,ia,nu,ia,irpt_ref)
     805                 :             :         end if
     806                 :             :       end do
     807                 :             :     end do
     808                 :             :   end do
     809                 :             : 
     810         [ -  + ]:          67 :  if (present(option)) then
     811         [ #  # ]:           0 :    if (option == 1) then
     812   [ #  #  #  #  :           0 :      ifc%short_atmfrc = atmfrc(:,:,:,:,:)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     813         [ #  # ]:           0 :    else if (option == 2) then
     814   [ #  #  #  #  :           0 :      ifc%ewald_atmfrc = atmfrc(:,:,:,:,:)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     815                 :             :    end if
     816                 :             :  else
     817   [ +  -  +  +  :     5134332 :    ifc%atmfrc(:,:,:,:,:) = atmfrc(:,:,:,:,:)
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                +  +  + ]
     818                 :             :  end if
     819                 :             : 
     820                 :          67 :  end subroutine harmonics_terms_applySumRule
     821                 :             : !!***
     822                 :             : 
     823   [ #  #  #  #  :           0 : end module m_harmonics_terms
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     824                 :             : !!***
        

Generated by: LCOV version 2.3-1