LCOV - code coverage report
Current view: top level - src/78_effpot - m_anharmonics_terms.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 43.5 % 186 81
Test Date: 2026-11-12 07:43:35 Functions: 58.3 % 12 7
Branches: 29.6 % 588 174

             Branch data     Line data    Source code
       1                 :             : !!****f* ABINIT/m_anharmonics_terms
       2                 :             : !!
       3                 :             : !! NAME
       4                 :             : !! m_anharmonics_term
       5                 :             : !!
       6                 :             : !! FUNCTION
       7                 :             : !! Module with datatype and tools for the anharmonics 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_anharmonics_terms
      26                 :             : 
      27                 :             :  use defs_basis
      28                 :             :  use m_errors
      29                 :             :  use m_abicore
      30                 :             :  use m_polynomial_coeff
      31                 :             :  use m_ifc, only : ifc_type
      32                 :             :  use m_supercell, only: getPBCIndexes_supercell
      33                 :             :  use m_xmpi
      34                 :             : 
      35                 :             :  implicit none
      36                 :             : 
      37                 :             :  public :: anharmonics_terms_init
      38                 :             :  public :: anharmonics_terms_free
      39                 :             :  public :: anharmonics_terms_freeCoeffs
      40                 :             :  public :: anharmonics_terms_evaluateElastic
      41                 :             :  public :: anharmonics_terms_evaluateIFCStrainCoupling
      42                 :             :  public :: anharmonics_terms_setCoeffs
      43                 :             :  public :: anharmonics_terms_setElastic3rd
      44                 :             :  public :: anharmonics_terms_setElastic4th
      45                 :             :  public :: anharmonics_terms_setElasticDispCoupling
      46                 :             :  public :: anharmonics_terms_setStrainPhononCoupling
      47                 :             : 
      48                 :             : !!***
      49                 :             : 
      50                 :             : !!****t* defs_abitypes/anharmonics_terms_type
      51                 :             : !! NAME
      52                 :             : !! anharmonics_terms_type
      53                 :             : !!
      54                 :             : !! FUNCTION
      55                 :             : !! datatype for a effective potential constructed.
      56                 :             : !!
      57                 :             : !! SOURCE
      58                 :             : 
      59                 :             :  type, public :: anharmonics_terms_type
      60                 :             : 
      61                 :             :    integer :: ncoeff = 0
      62                 :             : !    nterm store the number of coefficients
      63                 :             : 
      64                 :             :    logical ::  has_elastic3rd
      65                 :             : !   Flag to know if the 3rd derivatives with respect to strain is present
      66                 :             : 
      67                 :             :    logical ::  has_elastic4th
      68                 :             : !   Flag to know if the 3rd derivatives with respect to strain is present
      69                 :             : 
      70                 :             :    logical ::  has_strain_coupling
      71                 :             : !   Flag to know if the 3rd derivatives with respect to strain and 2 atom disp is present
      72                 :             : 
      73                 :             :    logical ::  has_elastic_displ
      74                 :             : !   Flag to know if the 3rd derivatives with respect to 2 strain and 3 atom disp is present
      75                 :             : 
      76                 :             :    logical :: bounded
      77                 :             : !   True : the model is bounded
      78                 :             : 
      79                 :             :    type(polynomial_coeff_type),dimension(:),allocatable :: coefficients
      80                 :             : !    array with all the coefficients from  polynomial coefficients
      81                 :             : 
      82                 :             :    real(dp) :: elastic3rd(6,6,6)
      83                 :             : !    elastic_constant(6,6,6)
      84                 :             : !    Elastic tensor Hartree
      85                 :             : 
      86                 :             :    real(dp) :: elastic4th(6,6,6,6)
      87                 :             : !    elastic_constant(6,6,6)
      88                 :             : !    Elastic tensor Hartree
      89                 :             : 
      90                 :             :    real(dp), allocatable :: elastic_displacement(:,:,:,:)
      91                 :             : !    elastic_displacement(6,6,3,natom)
      92                 :             : !    internal strain tensor
      93                 :             : 
      94                 :             :    type(ifc_type),dimension(:),allocatable :: phonon_strain
      95                 :             : !   Array of ifc with phonon_strain coupling for each strain
      96                 :             : 
      97                 :             :  end type anharmonics_terms_type
      98                 :             : !!***
      99                 :             : 
     100                 :             : CONTAINS  !===========================================================================================
     101                 :             : 
     102                 :             : 
     103                 :             : !!****f* m_anharmonics_terms/anharmonics_terms_init
     104                 :             : !!
     105                 :             : !! NAME
     106                 :             : !! anharmonics_terms_init
     107                 :             : !!
     108                 :             : !! FUNCTION
     109                 :             : !! Initialize anharmonics_terms datatype
     110                 :             : !!
     111                 :             : !! INPUTS
     112                 :             : !! natom  = number of atoms in primitive cell
     113                 :             : !! ncoeff = number of coefficient for the fited polynome
     114                 :             : !! bounded = optional, flag to now if the model in bounded
     115                 :             : !! elastic3rd(6,6,6) = optional,3rd order of the elastic constants
     116                 :             : !! elastic4th(6,6,6,6) = optional,4st order of the elastic constants
     117                 :             : !! elastic_displacement(6,6,3,natom) = optional,elastic constant - force coupling
     118                 :             : !! phonon_strain<type(ifc_type)>(6) = optional,phonon strain couling
     119                 :             : !! coeffs<type(polynomial_coeff_type)>(ncoeff) = optional,datatype with polynomial coefficients
     120                 :             : !!
     121                 :             : !! OUTPUT
     122                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype to be initialized
     123                 :             : !!
     124                 :             : !! SOURCE
     125                 :             : 
     126   [ -  +  -  -  :          76 : subroutine anharmonics_terms_init(anharmonics_terms,natom,ncoeff,&
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                -  -  - ]
     127                 :             : &                                 bounded,elastic3rd,elastic4th,elastic_displacement,&
     128                 :           0 : &                                 phonon_strain,coeffs)
     129                 :             : 
     130                 :             : !Arguments ------------------------------------
     131                 :             : !scalars
     132                 :             :  integer, intent(in) :: natom,ncoeff
     133                 :             :  type(anharmonics_terms_type), intent(out) :: anharmonics_terms
     134                 :             :  real(dp),optional,intent(in) :: elastic_displacement(6,6,3,natom)
     135                 :             :  real(dp),optional,intent(in) :: elastic3rd(6,6,6),elastic4th(6,6,6,6)
     136                 :             :  type(polynomial_coeff_type),optional :: coeffs(ncoeff)
     137                 :             :  type(ifc_type),optional,intent(in) :: phonon_strain(6)
     138                 :             :  logical,optional,intent(in) :: bounded
     139                 :             : !arrays
     140                 :             : !Local variables-------------------------------
     141                 :             : !scalar
     142                 :             : !arrays
     143                 :             :  character(len=500) :: msg
     144                 :             : 
     145                 :             : ! *************************************************************************
     146                 :             : 
     147                 :          76 :  call anharmonics_terms_free(anharmonics_terms)
     148                 :             : 
     149                 :             : ! Check the number of atoms
     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                 :             : !Allocation of phonon strain coupling array (3rd order)
     158         [ -  + ]:          76 :  if(present(phonon_strain)) then
     159                 :           0 :    call anharmonics_terms_setStrainPhononCoupling(anharmonics_terms,natom,phonon_strain)
     160                 :             :  end if
     161                 :             : 
     162                 :             : !Set the 3rd order elastic tensor
     163   [ +  +  +  +  :       19684 :  anharmonics_terms%elastic3rd = zero
                   +  + ]
     164                 :          76 :  anharmonics_terms%has_elastic3rd = .FALSE.
     165         [ -  + ]:          76 :  if(present(elastic3rd))then
     166                 :           0 :    call anharmonics_terms_setElastic3rd(anharmonics_terms,elastic3rd)
     167                 :             :  end if
     168                 :             : 
     169                 :             : !Set the 3rd order elastic tensor
     170   [ +  +  +  +  :      118180 :  anharmonics_terms%elastic4th = zero
             +  +  +  + ]
     171                 :          76 :  anharmonics_terms%has_elastic4th = .FALSE.
     172         [ -  + ]:          76 :  if(present(elastic4th))then
     173                 :           0 :    call anharmonics_terms_setElastic4th(anharmonics_terms,elastic4th)
     174                 :             :  end if
     175                 :             : 
     176                 :             : !Allocation of 3rd order with respecto to 2 strain and 1 atomic displacement
     177         [ -  + ]:          76 :  if(present(elastic_displacement))then
     178                 :           0 :    call anharmonics_terms_setElasticDispCoupling(anharmonics_terms,natom,elastic_displacement)
     179                 :             :  end if
     180                 :             : 
     181                 :          76 :  anharmonics_terms%ncoeff = 0
     182                 :             : 
     183                 :             : !Allocation of the coefficient
     184         [ -  + ]:          76 :   if(present(coeffs))then
     185         [ #  # ]:           0 :    if(ncoeff /= size(coeffs))then
     186                 :             :      write(msg, '(a)' )&
     187                 :           0 : &        ' ncoeff has not the same size than coeffs array, '
     188                 :           0 :      ABI_BUG(msg)
     189                 :             :    end if
     190                 :           0 :    call anharmonics_terms_setCoeffs(coeffs,anharmonics_terms,ncoeff)
     191                 :             :  end if
     192                 :             : 
     193                 :             : !Set the flag bounded
     194         [ -  + ]:          76 :  if(present(bounded))then
     195                 :           0 :    anharmonics_terms%bounded = bounded
     196                 :             :  else
     197                 :          76 :    anharmonics_terms%bounded = .FALSE.
     198                 :             :  end if
     199                 :             : 
     200         [ -  + ]:          76 : end subroutine anharmonics_terms_init
     201                 :             : !!***
     202                 :             : 
     203                 :             : !****f* m_anharmonics_terms/anharmonics_terms_free
     204                 :             : !!
     205                 :             : !! NAME
     206                 :             : !! anharmonics_terms_free
     207                 :             : !!
     208                 :             : !! FUNCTION
     209                 :             : !! deallocate all dynamic memory for this anharmonics_terms datatype
     210                 :             : !!
     211                 :             : !! INPUTS
     212                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype to be free
     213                 :             : !!
     214                 :             : !! OUTPUT
     215                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype to be free
     216                 :             : !!
     217                 :             : !! SOURCE
     218                 :             : 
     219                 :         610 : subroutine anharmonics_terms_free(anharmonics_terms)
     220                 :             : 
     221                 :             : !Arguments ------------------------------------
     222                 :             : !scalars
     223                 :             : !array
     224                 :             :   type(anharmonics_terms_type), intent(inout) :: anharmonics_terms
     225                 :             : 
     226                 :             : !Local variables-------------------------------
     227                 :             : !scalars
     228                 :             :   integer :: ii
     229                 :             : !array
     230                 :             : 
     231                 :             : ! *************************************************************************
     232                 :             : 
     233                 :         610 :    anharmonics_terms%has_elastic3rd = .FALSE.
     234                 :         610 :    anharmonics_terms%has_strain_coupling  = .FALSE.
     235                 :         610 :    anharmonics_terms%has_elastic_displ = .FALSE.
     236                 :         610 :    anharmonics_terms%bounded = .FALSE.
     237                 :             : 
     238         [ -  + ]:         610 :   if(allocated(anharmonics_terms%elastic_displacement)) then
     239   [ #  #  #  #  :           0 :     anharmonics_terms%elastic_displacement=zero
             #  #  #  # ]
     240                 :           0 :     ABI_SFREE(anharmonics_terms%elastic_displacement)
     241                 :             :   end if
     242                 :             : 
     243         [ +  + ]:         610 :   if(allocated(anharmonics_terms%phonon_strain))then
     244         [ +  + ]:         315 :     do ii = 1,6
     245                 :         315 :        call anharmonics_terms%phonon_strain(ii)%free()
     246                 :             :     end do
     247   [ +  -  +  +  :         315 :     ABI_SFREE(anharmonics_terms%phonon_strain)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                      + ]
     248                 :             :   end if
     249                 :             : 
     250                 :         610 :   call anharmonics_terms_freeCoeffs(anharmonics_terms)
     251                 :             : 
     252   [ +  +  +  +  :      157990 :   anharmonics_terms%elastic3rd = zero
                   +  + ]
     253                 :             : 
     254                 :             : 
     255                 :         610 : end subroutine anharmonics_terms_free
     256                 :             : !!***
     257                 :             : 
     258                 :             : !****f* m_anharmonics_terms/anharmonics_terms_freeCoeffs
     259                 :             : !!
     260                 :             : !! NAME
     261                 :             : !! anharmonics_terms_freeCoeffs
     262                 :             : !!
     263                 :             : !! FUNCTION
     264                 :             : !! deallocate all dynamic memory for the coefficients
     265                 :             : !! of this  anharmonics_terms datatype
     266                 :             : !!
     267                 :             : !! INPUTS
     268                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype to be free
     269                 :             : !!
     270                 :             : !! OUTPUT
     271                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype to be free
     272                 :             : !!
     273                 :             : !!
     274                 :             : !! SOURCE
     275                 :             : 
     276                 :         686 : subroutine anharmonics_terms_freeCoeffs(anharmonics_terms)
     277                 :             : 
     278                 :             : !Arguments ------------------------------------
     279                 :             : !scalars
     280                 :             : !array
     281                 :             :   type(anharmonics_terms_type), intent(inout) :: anharmonics_terms
     282                 :             : !Local variables-------------------------------
     283                 :             : !scalars
     284                 :             :   integer :: ii
     285                 :             : !array
     286                 :             : 
     287                 :             : ! *************************************************************************
     288                 :             : 
     289         [ +  + ]:         686 :   if(allocated(anharmonics_terms%coefficients))then
     290         [ +  + ]:        2146 :     do ii=1,anharmonics_terms%ncoeff
     291                 :        2146 :       call polynomial_coeff_free(anharmonics_terms%coefficients(ii))
     292                 :             :     end do
     293   [ +  -  +  +  :        2146 :     ABI_SFREE(anharmonics_terms%coefficients)
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
                      + ]
     294                 :             :   end if
     295                 :             : 
     296                 :         686 :   anharmonics_terms%ncoeff = 0
     297                 :             : 
     298                 :         686 : end subroutine anharmonics_terms_freeCoeffs
     299                 :             : !!***
     300                 :             : 
     301                 :             : !****f* m_anharmonics_terms/anharmonics_terms_setCoeffs
     302                 :             : !!
     303                 :             : !! NAME
     304                 :             : !! anharmonics_terms_setCoeffs
     305                 :             : !!
     306                 :             : !! FUNCTION
     307                 :             : !! Set the coefficients
     308                 :             : !!
     309                 :             : !! INPUTS
     310                 :             : !! coeffs(ncoeff)<type(polynomial_coeff_type)> = array with datatype polynomial_coeff_type
     311                 :             : !! ncoeff = number of coefficient
     312                 :             : !!
     313                 :             : !! OUTPUT
     314                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype
     315                 :             : !!
     316                 :             : !!
     317                 :             : !! SOURCE
     318                 :             : 
     319                 :         192 : subroutine anharmonics_terms_setCoeffs(coeffs,anharmonics_terms,ncoeff)
     320                 :             : 
     321                 :             :  use m_polynomial_coeff
     322                 :             : 
     323                 :             : !Arguments ------------------------------------
     324                 :             : !scalars
     325                 :             :   integer,intent(in) :: ncoeff
     326                 :             : !array
     327                 :             :   type(anharmonics_terms_type),intent(inout) :: anharmonics_terms
     328                 :             :   type(polynomial_coeff_type),intent(in) :: coeffs(ncoeff)
     329                 :             : !Local variables-------------------------------
     330                 :             : !scalar
     331                 :             :   integer :: ii
     332                 :             :   character(len=500) :: msg
     333                 :             : !array
     334                 :             : ! *************************************************************************
     335                 :             : 
     336         [ -  + ]:          96 :   if(ncoeff /= size(coeffs))then
     337                 :             :     write(msg, '(a)' )&
     338                 :           0 : &        ' ncoeff has not the same size than coeffs array, '
     339                 :           0 :     ABI_BUG(msg)
     340                 :             :   end if
     341                 :             : 
     342                 :             : ! 1-deallocation of the previous value
     343         [ +  + ]:          96 :   if(allocated(anharmonics_terms%coefficients))then
     344         [ +  + ]:           9 :     do ii=1,anharmonics_terms%ncoeff
     345                 :           9 :       call polynomial_coeff_free(anharmonics_terms%coefficients(ii))
     346                 :             :     end do
     347   [ +  -  +  +  :           9 :     ABI_SFREE(anharmonics_terms%coefficients)
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
                      + ]
     348                 :             :   end if
     349                 :             : 
     350                 :             : ! Allocation of the new array
     351                 :          96 :   anharmonics_terms%ncoeff = ncoeff
     352   [ -  +  +  -  :        2347 :   ABI_MALLOC(anharmonics_terms%coefficients,(ncoeff))
          +  -  +  -  -  
          +  -  +  -  +  
             +  +  +  - ]
     353         [ +  + ]:        2155 :   do ii=1,anharmonics_terms%ncoeff
     354                 :             :     call polynomial_coeff_init(coeffs(ii)%coefficient,coeffs(ii)%nterm,&
     355                 :             :       &                              anharmonics_terms%coefficients(ii),&
     356                 :             :       &                              coeffs(ii)%terms, &
     357                 :        2155 :       &                              name=coeffs(ii)%name)
     358                 :             :   end do
     359                 :             : 
     360                 :          96 : end subroutine anharmonics_terms_setCoeffs
     361                 :             : !!***
     362                 :             : 
     363                 :             : !****f* m_anharmonics_terms/anharmonics_terms_setElastic3rd
     364                 :             : !!
     365                 :             : !! NAME
     366                 :             : !! anharmonics_terms_setElastic3rd
     367                 :             : !!
     368                 :             : !! FUNCTION
     369                 :             : !! Set the 3rd order derivative of with respect to 3 strain
     370                 :             : !!
     371                 :             : !! INPUTS
     372                 :             : !! elastics(6,6,6) = 3d order of elastics constant
     373                 :             : !!
     374                 :             : !! OUTPUT
     375                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype
     376                 :             : !!
     377                 :             : !! SOURCE
     378                 :             : 
     379                 :          45 : subroutine anharmonics_terms_setElastic3rd(anharmonics_terms,elastics)
     380                 :             : 
     381                 :             : !Arguments ------------------------------------
     382                 :             : !scalars
     383                 :             : !array
     384                 :             :   type(anharmonics_terms_type),intent(inout) :: anharmonics_terms
     385                 :             :   real(dp),intent(in) :: elastics(6,6,6)
     386                 :             : !Local variables-------------------------------
     387                 :             : !scalar
     388                 :             : !array
     389                 :             : ! *************************************************************************
     390                 :             : 
     391                 :             : ! 1-reinitialise the previous value
     392   [ +  +  +  +  :       11655 :   anharmonics_terms%elastic3rd(:,:,:) = zero
                   +  + ]
     393                 :          45 :   anharmonics_terms%has_elastic3rd = .FALSE.
     394                 :             : 
     395                 :             : ! 2-Allocation of the new array
     396   [ +  +  +  +  :       11655 :   anharmonics_terms%elastic3rd(:,:,:) = elastics(:,:,:)
                   +  + ]
     397                 :             : 
     398                 :             : ! 3-Set the flag
     399   [ +  +  +  +  :       11655 :   if(any(abs(anharmonics_terms%elastic3rd)> tol15)) then
          +  +  +  -  -  
                      + ]
     400                 :           0 :     anharmonics_terms%has_elastic3rd = .TRUE.
     401                 :             :   end if
     402                 :             : 
     403                 :          96 : end subroutine anharmonics_terms_setElastic3rd
     404                 :             : !!***
     405                 :             : 
     406                 :             : !****f* m_anharmonics_terms/anharmonics_terms_setElastic4th
     407                 :             : !!
     408                 :             : !! NAME
     409                 :             : !! anharmonics_terms_setElastic4th
     410                 :             : !!
     411                 :             : !! FUNCTION
     412                 :             : !! Set the 4th order derivative of with respect to 4 strain
     413                 :             : !!
     414                 :             : !! INPUTS
     415                 :             : !! elastics = 4th order of elastics constant
     416                 :             : !!
     417                 :             : !! OUTPUT
     418                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype
     419                 :             : !!
     420                 :             : !!
     421                 :             : !! SOURCE
     422                 :             : 
     423                 :           0 : subroutine anharmonics_terms_setElastic4th(anharmonics_terms,elastics)
     424                 :             : 
     425                 :             : !Arguments ------------------------------------
     426                 :             : !scalars
     427                 :             : !array
     428                 :             :   type(anharmonics_terms_type),intent(inout) :: anharmonics_terms
     429                 :             :   real(dp),intent(in) :: elastics(6,6,6,6)
     430                 :             : !Local variables-------------------------------
     431                 :             : !scalar
     432                 :             : !array
     433                 :             : ! *************************************************************************
     434                 :             : 
     435                 :             : ! 1-reinitialise the previous value
     436   [ #  #  #  #  :           0 :   anharmonics_terms%elastic4th(:,:,:,:) = zero
             #  #  #  # ]
     437                 :           0 :   anharmonics_terms%has_elastic4th = .FALSE.
     438                 :             : 
     439                 :             : ! 2-Allocation of the new array
     440   [ #  #  #  #  :           0 :   anharmonics_terms%elastic4th(:,:,:,:) = elastics(:,:,:,:)
             #  #  #  # ]
     441                 :             : 
     442                 :             : ! 3-Set the flag
     443   [ #  #  #  #  :           0 :   if(any(abs(anharmonics_terms%elastic4th)> tol15)) then
          #  #  #  #  #  
                #  #  # ]
     444                 :           0 :     anharmonics_terms%has_elastic4th = .TRUE.
     445                 :             :   end if
     446                 :             : 
     447                 :           0 : end subroutine anharmonics_terms_setElastic4th
     448                 :             : !!***
     449                 :             : 
     450                 :             : 
     451                 :             : !****f* m_anharmonics_terms/anharmonics_terms_setStrainPhononCoupling
     452                 :             : !!
     453                 :             : !! NAME
     454                 :             : !! anharmonics_terms_setStrainPhononCoupling
     455                 :             : !!
     456                 :             : !! FUNCTION
     457                 :             : !! Set the strain-phonon coupling
     458                 :             : !!
     459                 :             : !! INPUTS
     460                 :             : !! strain_phonon(6)<type(ifc_type) = strain-phonon coupling
     461                 :             : !! natom = number of atoms
     462                 :             : !!
     463                 :             : !! OUTPUT
     464                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype
     465                 :             : !!
     466                 :             : !! SOURCE
     467                 :             : 
     468                 :          45 : subroutine anharmonics_terms_setStrainPhononCoupling(anharmonics_terms,natom,phonon_strain)
     469                 :             : 
     470                 :             : !Arguments ------------------------------------
     471                 :             : !scalars
     472                 :             :   integer, intent(in) :: natom
     473                 :             : !array
     474                 :             :   type(anharmonics_terms_type),intent(inout) :: anharmonics_terms
     475                 :             :   type(ifc_type),intent(in) :: phonon_strain(6)
     476                 :             : !Local variables-------------------------------
     477                 :             : !scalar
     478                 :             :   integer :: ii,nrpt
     479                 :             :   character(500) :: msg
     480                 :             : !array
     481                 :             : ! *************************************************************************
     482                 :             : 
     483                 :             : ! 1-Do some check
     484         [ +  + ]:         315 :   do ii=1,6
     485                 :             : !PROBLEM eos_gnu_13.2_openmpi
     486                 :             : !   if(natom /= size(phonon_strain(ii)%atmfrc,2).or.&
     487         [ -  + ]:         270 :     if( &
     488                 :             : !ENDPROBLEM
     489                 :          45 : &      phonon_strain(ii)%nrpt < 0)then
     490                 :             :       write(msg, '(a)' )&
     491                 :           0 : &        ' natom or/and nrpt have not the same size than phonon_strain array. '
     492                 :           0 :       ABI_BUG(msg)
     493                 :             :     end if
     494                 :             :   end do
     495                 :             : 
     496                 :             : ! 1-reinitialise the previous value
     497                 :          45 :   anharmonics_terms%has_strain_coupling  = .FALSE.
     498         [ -  + ]:          45 :   if(allocated(anharmonics_terms%phonon_strain))then
     499         [ #  # ]:           0 :     do ii = 1,6
     500                 :           0 :        call anharmonics_terms%phonon_strain(ii)%free()
     501                 :             :     end do
     502   [ #  #  #  #  :           0 :     ABI_SFREE(anharmonics_terms%phonon_strain)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     503                 :             :   end if
     504                 :             : 
     505                 :             : ! 2-Allocation of the new array and filling
     506   [ -  +  -  +  :         585 :  ABI_MALLOC(anharmonics_terms%phonon_strain,(6))
          +  +  +  +  +  
                +  +  - ]
     507         [ +  + ]:         315 :  do ii = 1,6
     508                 :         270 :    nrpt = phonon_strain(ii)%nrpt
     509   [ -  +  +  -  :        1620 :    ABI_MALLOC(anharmonics_terms%phonon_strain(ii)%atmfrc,(3,natom,3,natom,nrpt))
          +  -  -  +  +  
          -  +  -  -  -  
          +  -  -  +  -  
             +  -  +  -  
                      + ]
     510   [ +  -  -  -  :         810 :    ABI_MALLOC(anharmonics_terms%phonon_strain(ii)%cell,(3,nrpt))
          +  -  -  +  -  
             +  -  +  -  
                      + ]
     511                 :         270 :    anharmonics_terms%phonon_strain(ii)%nrpt   = phonon_strain(ii)%nrpt
     512   [ -  +  -  -  :         270 :    anharmonics_terms%phonon_strain(ii)%atmfrc(:,:,:,:,:) = phonon_strain(ii)%atmfrc(:,:,:,:,:)
          -  -  -  -  -  
                      - ]
     513   [ -  +  -  - ]:         270 :    anharmonics_terms%phonon_strain(ii)%cell(:,:)   = phonon_strain(ii)%cell(:,:)
     514                 :             : 
     515                 :             : !3-Set the flag
     516   [ -  +  -  -  :         315 :    if(any(abs(anharmonics_terms%phonon_strain(ii)%atmfrc)> tol15)) then
          -  -  -  -  -  
             -  -  -  -  
                      + ]
     517                 :           0 :      anharmonics_terms%has_strain_coupling  = .TRUE.
     518                 :             : !  If there is no value inside the array,
     519                 :             : !  We don't need to store it
     520                 :             :    else
     521         [ +  - ]:         270 :      ABI_SFREE(anharmonics_terms%phonon_strain(ii)%atmfrc)
     522         [ +  - ]:         270 :      ABI_SFREE(anharmonics_terms%phonon_strain(ii)%cell)
     523                 :         270 :      anharmonics_terms%phonon_strain(ii)%nrpt = 0
     524                 :             :    end if
     525                 :             :  end do
     526                 :             : 
     527                 :          45 : end subroutine anharmonics_terms_setStrainPhononCoupling
     528                 :             : !!***
     529                 :             : 
     530                 :             : !****f* m_anharmonics_terms/anharmonics_terms_setElasticDispCoupling
     531                 :             : !!
     532                 :             : !! NAME
     533                 :             : !! anharmonics_terms_setElasticDispCoupling
     534                 :             : !!
     535                 :             : !! FUNCTION
     536                 :             : !! Set the Elastic displacement coupling
     537                 :             : !!
     538                 :             : !! INPUTS
     539                 :             : !! elastic_displacement(6,6,3,natom) = elastic displacement coupling
     540                 :             : !! natom = number of atom
     541                 :             : !!
     542                 :             : !! OUTPUT
     543                 :             : !! anharmonics_terms<type(anharmonics_terms_type)> = anharmonics_terms datatype
     544                 :             : !!
     545                 :             : !!
     546                 :             : !! SOURCE
     547                 :             : 
     548                 :          38 : subroutine anharmonics_terms_setElasticDispCoupling(anharmonics_terms,natom,elastic_displacement)
     549                 :             : 
     550                 :             : !Arguments ------------------------------------
     551                 :             : !scalars
     552                 :             :   integer, intent(in) :: natom
     553                 :             : !array
     554                 :             :   type(anharmonics_terms_type),intent(inout) :: anharmonics_terms
     555                 :             :   real(dp),intent(in) :: elastic_displacement(6,6,3,natom)
     556                 :             : !Local variables-------------------------------
     557                 :             : !scalar
     558                 :             :   character(500) :: msg
     559                 :             : !array
     560                 :             : ! *************************************************************************
     561                 :             : 
     562                 :             : ! 1-Do some check
     563         [ -  + ]:          38 :   if(natom /= size(elastic_displacement,4)) then
     564                 :             :     write(msg, '(a)' )&
     565                 :           0 : &        ' natom has not the same size elastic_displacement array. '
     566                 :           0 :     ABI_BUG(msg)
     567                 :             :   end if
     568                 :             : 
     569                 :             : ! 1-reinitialise the previous value
     570                 :          38 :   anharmonics_terms%has_elastic_displ = .FALSE.
     571         [ -  + ]:          38 :   if(allocated(anharmonics_terms%elastic_displacement))then
     572                 :           0 :     ABI_SFREE(anharmonics_terms%elastic_displacement)
     573                 :             :   end if
     574                 :             : 
     575                 :             : ! 2-Allocation of the new array and filling
     576   [ -  +  +  -  :         114 :   ABI_MALLOC(anharmonics_terms%elastic_displacement,(6,6,3,natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     577   [ +  +  +  +  :       26558 :   anharmonics_terms%elastic_displacement(:,:,:,:) = elastic_displacement(:,:,:,:)
             +  +  +  + ]
     578                 :             : 
     579                 :             : ! 3-Set the flag
     580   [ +  +  +  +  :       26558 :   if(any(abs(anharmonics_terms%elastic_displacement)> tol15)) then
          +  +  +  +  +  
                -  -  + ]
     581                 :           0 :     anharmonics_terms%has_elastic_displ = .TRUE.
     582                 :             :   else
     583                 :             : !   If there is no value inside the array,
     584                 :             : !   We don't need to store it
     585         [ +  - ]:          38 :     ABI_SFREE(anharmonics_terms%elastic_displacement)
     586                 :             :   end if
     587                 :             : 
     588                 :          38 : end subroutine anharmonics_terms_setElasticDispCoupling
     589                 :             : !!***
     590                 :             : 
     591                 :             : !!****f* m_effective_potential/anharmonics_terms_evaluateElastic
     592                 :             : !! NAME
     593                 :             : !!  anharmonics_terms_evaluateElastic
     594                 :             : !!
     595                 :             : !! FUNCTION
     596                 :             : !! Compute the energy, stresses and forces related to the application of strain
     597                 :             : !!
     598                 :             : !! INPUTS
     599                 :             : !! disp(3,natom_sc) = atomics displacement between configuration and the reference
     600                 :             : !! natom = number of atom in the supercell
     601                 :             : !! natom_uc = number of atom in the unit cell
     602                 :             : !! ncell  = number of cell
     603                 :             : !! strain(6) =  strain to apply
     604                 :             : !! elastic3rd(6,6,6) = 3 order derivatives with respect to to 3 strain
     605                 :             : !! elastic4th(6,6,66,) = 4 order derivatives with respect to to 4 strain
     606                 :             : !! elastic_displacement(6,6,3,natom) = 3 order derivatives with respect to 2 strain and 1 Atom disp
     607                 :             : !!
     608                 :             : !! OUTPUT
     609                 :             : !!   energy = contribution of the ifc to the energy
     610                 :             : !!   fcart(3,natom) = contribution of the ifc to the forces
     611                 :             : !!   strten(6) = contribution to the stress tensor
     612                 :             : !!
     613                 :             : !! SOURCE
     614                 :             : !!
     615                 :           0 : subroutine anharmonics_terms_evaluateElastic(disp,energy,fcart,natom,natom_uc,ncell,strten,strain,&
     616                 :             : &                                            elastic3rd,elastic4th,elastic_displacement)
     617                 :             : 
     618                 :             :  real(dp),intent(out):: energy
     619                 :             :  integer, intent(in) :: natom,natom_uc,ncell
     620                 :             : ! array
     621                 :             :  real(dp),optional,intent(in) :: elastic3rd(6,6,6),elastic4th(6,6,6,6)
     622                 :             :  real(dp),optional,intent(in) :: elastic_displacement(6,6,3,natom)
     623                 :             :  real(dp),intent(out):: strten(6)
     624                 :             :  real(dp),intent(out):: fcart(3,natom)
     625                 :             :  real(dp),intent(in) :: disp(3,natom)
     626                 :             :  real(dp),intent(in) :: strain(6)
     627                 :             : 
     628                 :             :  !Local variables-------------------------------
     629                 :             : ! scalar
     630                 :             :  integer :: ia,ii,mu,alpha,beta,gamma,delta,d1,d2
     631                 :             :  real(dp):: cijk
     632                 :             :  logical :: has_elastic3rd,has_elastic4th,has_elastic_displ
     633                 :             : ! array
     634                 :             : ! *************************************************************************
     635                 :             : 
     636                 :             : !Reset output and flags
     637                 :           0 :  energy = zero
     638   [ #  #  #  # ]:           0 :  fcart = zero
     639                 :           0 :  strten = zero
     640                 :           0 :  has_elastic3rd    = .FALSE.
     641                 :           0 :  has_elastic4th    = .FALSE.
     642                 :           0 :  has_elastic_displ = .FALSE.
     643                 :           0 :  d1=0;d2=0
     644                 :             : 
     645                 :             : !Set the flags
     646         [ #  # ]:           0 :  if(present(elastic3rd)) has_elastic3rd = .TRUE.
     647         [ #  # ]:           0 :  if(present(elastic4th)) then
     648                 :           0 :    has_elastic4th = .TRUE.
     649                 :           0 :    d1=1;d2=6
     650                 :             :  end if
     651         [ #  # ]:           0 :  if(present(elastic_displacement)) has_elastic_displ = .TRUE.
     652                 :             : 
     653                 :             : !1-Treat 3rd order elastic constants
     654         [ #  # ]:           0 :  if (has_elastic3rd.or.has_elastic4th) then
     655         [ #  # ]:           0 :    do alpha=1,6
     656         [ #  # ]:           0 :      do beta=1,6
     657         [ #  # ]:           0 :        do gamma=1,6
     658                 :           0 :          cijk = ncell*elastic3rd(alpha,beta,gamma)
     659                 :             : !        Accumulate energy
     660                 :           0 :          energy = energy + sixth*cijk*strain(alpha)*strain(beta)*strain(gamma)
     661                 :             : !        Accumulate stresses contributions
     662                 :           0 :          strten(alpha)=strten(alpha)+ half*cijk*strain(beta)*strain(gamma)
     663         [ #  # ]:           0 :          do delta=d1,d2
     664                 :           0 :            cijk = ncell*elastic4th(alpha,beta,gamma,delta)
     665                 :             : !          Accumulate energy
     666                 :             :            energy = energy + (1/24.)*cijk*strain(alpha)*strain(beta)*&
     667                 :           0 : &                                                  strain(gamma)*strain(delta)
     668                 :             : !          Accumulate stresses contributions
     669                 :             :            strten(alpha)=strten(alpha)+ sixth*cijk*strain(beta)*strain(gamma)*&
     670                 :           0 : &                                                           strain(delta)
     671                 :             :          end do
     672                 :             :        end do
     673                 :             :      end do
     674                 :             :    end do
     675                 :             :  end if
     676                 :             : 
     677                 :             : !2-Part due to the internat strain
     678         [ #  # ]:           0 :  if(has_elastic_displ)then
     679                 :             :    ii = 1
     680         [ #  # ]:           0 :    do ia = 1,natom
     681         [ #  # ]:           0 :      do mu = 1,3
     682         [ #  # ]:           0 :        do beta=1,6
     683         [ #  # ]:           0 :          do alpha=1,6
     684                 :           0 :            cijk = elastic_displacement(alpha,beta,mu,ii)
     685                 :             : !          Accumulte for this atom
     686                 :           0 :            energy = energy + sixth*cijk*strain(alpha)*strain(beta)*disp(mu,ia)
     687                 :           0 :            fcart(mu,ia) = fcart(mu,ia)   +  half*cijk*strain(alpha)*strain(beta)
     688                 :           0 :            strten(alpha) = strten(alpha) +  half*cijk*strain(beta)*disp(mu,ia)
     689                 :             :          end do
     690                 :             :        end do
     691                 :             :      end do
     692                 :           0 :      ii = ii +1
     693                 :             : !    Reset to 1 if the number of atoms is superior than in the initial cell
     694         [ #  # ]:           0 :      if(ii==natom_uc+1) ii = 1
     695                 :             :    end do
     696                 :             :  end if
     697                 :             : 
     698                 :           0 : end subroutine anharmonics_terms_evaluateElastic
     699                 :             : !!***
     700                 :             : 
     701                 :             : !!****f* m_anharmonics_terms/anharmonics_terms_evaluateIFCStrainCoupling
     702                 :             : !! NAME
     703                 :             : !!  anharmonics_terms_evaluateIFCStrainCoupling
     704                 :             : !!
     705                 :             : !! FUNCTION
     706                 :             : !!  This fonction compute the harmonic part of the energy
     707                 :             : !!  of the supercell in the eff_pot
     708                 :             : !! INPUTS
     709                 :             : !!  strain_phonon(6)<type(ifc_type) = strain-phonon coupling
     710                 :             : !!  disp(3,natom_sc) = atomics displacement between configuration and the reference
     711                 :             : !!  natom = number of atoms in the supercell
     712                 :             : !!  natom_uc = number of atoms in the unit cell
     713                 :             : !!  sc_size(3) = size of the supercell
     714                 :             : !!  cells(ncell) = number of the cells into the supercell (1,2,3,4,5)
     715                 :             : !!  ncell  = total number of cell to treat
     716                 :             : !!  index_cells(3,ncell) = indexes of the cells into  supercell (-1 -1 -1 ,...,1 1 1)
     717                 :             : !!  comm=MPI communicator
     718                 :             : !!
     719                 :             : !! OUTPUT
     720                 :             : !!   energy = contribution of the ifc to the energy
     721                 :             : !!   fcart(3,natom) = contribution of the ifc to the forces
     722                 :             : !!   strten(6) = contribution to the stress tensor
     723                 :             : !!
     724                 :             : !! PARENT
     725                 :             : !!   effective_potential_evaluate
     726                 :             : !!
     727                 :             : !! SOURCE
     728                 :             : 
     729                 :           0 : subroutine anharmonics_terms_evaluateIFCStrainCoupling(phonon_strain,disp,energy,fcart,natom,natom_uc,&
     730                 :           0 : &                                                      sc_size,strain,strten,cells,ncell,&
     731                 :           0 : &                                                      index_cells,comm)
     732                 :             : 
     733                 :             : !Arguments -------------------------------
     734                 :             : ! scalars
     735                 :             :   real(dp),intent(out) :: energy
     736                 :             :   integer,intent(in) :: natom,natom_uc,ncell
     737                 :             :   integer,intent(in) :: comm
     738                 :             : ! array
     739                 :             :   integer,intent(in) ::   cells(ncell),index_cells(ncell,3)
     740                 :             :   integer,intent(in) :: sc_size(3)
     741                 :             :   type(ifc_type),intent(in) :: phonon_strain(6)
     742                 :             :   real(dp),intent(in) :: disp(3,natom)
     743                 :             :   real(dp),intent(out) :: fcart(3,natom)
     744                 :             :   real(dp),intent(out) :: strten(6)
     745                 :             :   real(dp),intent(in) :: strain(6)
     746                 :             : !Local variables-------------------------------
     747                 :             : ! scalar
     748                 :             :   integer :: alpha
     749                 :             :   integer :: i1,i2,i3,ia,ib,icell,ii
     750                 :             :   integer :: irpt,jj,kk,ll,mu,nu
     751                 :             :   integer :: ierr
     752                 :             :   real(dp):: ifc
     753                 :             : ! array
     754                 :             :   integer :: cell_atom2(3)
     755                 :             :   character(500) :: msg
     756                 :             : 
     757                 :             : ! *************************************************************************
     758                 :             : 
     759   [ #  #  #  #  :           0 :   if (any(sc_size <= 0)) then
                   #  # ]
     760                 :           0 :     write(msg,'(a,a)')' sc_size can not be inferior or equal to zero'
     761                 :           0 :     ABI_ERROR(msg)
     762                 :             :   end if
     763                 :             : 
     764                 :             : ! Initialisation of variables
     765                 :           0 :   energy   = zero
     766   [ #  #  #  # ]:           0 :   fcart(:,:) = zero
     767                 :           0 :   strten(:) = zero
     768                 :             : 
     769         [ #  # ]:           0 :   do icell = 1,ncell
     770                 :           0 :     ii = (cells(icell)-1)*natom_uc
     771                 :           0 :     i1=index_cells(icell,1); i2=index_cells(icell,2); i3=index_cells(icell,3)
     772         [ #  # ]:           0 :     do alpha=1,6
     773         [ #  # ]:           0 :       do irpt = 1,phonon_strain(alpha)%nrpt
     774                 :             : !       get the cell of atom2  (0 0 0, 0 0 1...)
     775                 :           0 :         cell_atom2(1) =  i1 + phonon_strain(alpha)%cell(1,irpt)
     776                 :           0 :         cell_atom2(2) =  i2 + phonon_strain(alpha)%cell(2,irpt)
     777                 :           0 :         cell_atom2(3) =  i3 + phonon_strain(alpha)%cell(3,irpt)
     778                 :           0 :         call getPBCIndexes_supercell(cell_atom2(1:3),sc_size(1:3))
     779                 :             : !       index of the second atom in the displacement array
     780                 :             :         jj = (cell_atom2(1)-1)*sc_size(2)*sc_size(3)*natom_uc+&
     781                 :             : &            (cell_atom2(2)-1)*sc_size(3)*natom_uc+&
     782                 :           0 : &            (cell_atom2(3)-1)*natom_uc
     783         [ #  # ]:           0 :         do ib = 1, natom_uc
     784                 :           0 :           ll = jj + ib
     785         [ #  # ]:           0 :           do nu=1,3
     786         [ #  # ]:           0 :             do ia = 1, natom_uc
     787                 :           0 :               kk = ii + ia
     788         [ #  # ]:           0 :               do mu=1,3
     789                 :           0 :                 ifc = phonon_strain(alpha)%atmfrc(mu,ia,nu,ib,irpt)
     790                 :             : !               accumule energy
     791                 :           0 :                 energy =  energy + sixth*strain(alpha)*disp(mu,kk)*disp(nu,ll)*ifc
     792                 :             : !               accumule forces
     793                 :           0 :                 fcart(mu,kk) = fcart(mu,kk) + half*strain(alpha)*disp(nu,ll)*ifc
     794                 :             : !               accumule stresses
     795                 :           0 :                 strten(alpha) = strten(alpha) + half*disp(mu,kk)*disp(nu,ll)*ifc
     796                 :             :               end do
     797                 :             :             end do
     798                 :             :           end do
     799                 :             :         end do
     800                 :             :       end do
     801                 :             :     end do
     802                 :             :   end do
     803                 :             : 
     804                 :             : ! MPI_SUM
     805                 :           0 :   call xmpi_sum(energy, comm, ierr)
     806                 :           0 :   call xmpi_sum(fcart , comm, ierr)
     807                 :           0 :   call xmpi_sum(strten, comm, ierr)
     808                 :             : 
     809                 :           0 : end subroutine anharmonics_terms_evaluateIFCStrainCoupling
     810                 :             : !!***
     811   [ #  #  #  #  :           0 : end module m_anharmonics_terms
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     812                 :             : !!***
        

Generated by: LCOV version 2.3-1