LCOV - code coverage report
Current view: top level - src/78_effpot - m_lattice_langevin_mover.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 52 52
Test Date: 2026-11-08 08:00:28 Functions: 100.0 % 6 6
Branches: 56.0 % 168 94

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_lattice_langevin_mover
       2                 :             : !! NAME
       3                 :             : !! m_lattice_langevin_mover
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module contains the langevin  (NVT) lattice mover.
       7                 :             : !! It is a translation from the ASE (GPL licenced) Langevin mover python code to fortran.
       8                 :             : !! The original code can be found at
       9                 :             : !! https://gitlab.com/ase/ase/blob/master/ase/md/langevin.py
      10                 :             : !! The method is described in
      11                 :             : !! E. V.-Eijnden, and G. Ciccotti, Chem. Phys. Lett. 429, 310 (2006)
      12                 :             : !!  https://doi.org/10.1016/j.cplett.2006.07.086
      13                 :             : !!
      14                 :             : !!
      15                 :             : !! Datatypes:
      16                 :             : !!
      17                 :             : !! * lattice_langevin_mover_t: defines the lattice movers
      18                 :             : !!
      19                 :             : !! Subroutines:
      20                 :             : !! TODO: add this when F2003 doc style is determined.
      21                 :             : !!
      22                 :             : !!
      23                 :             : !! COPYRIGHT
      24                 :             : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      25                 :             : !! This file is distributed under the terms of the
      26                 :             : !! GNU General Public License, see ~abinit/COPYING
      27                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      28                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      29                 :             : !!
      30                 :             : !! SOURCE
      31                 :             : 
      32                 :             : 
      33                 :             : 
      34                 :             : #if defined HAVE_CONFIG_H
      35                 :             : #include "config.h"
      36                 :             : #endif
      37                 :             : 
      38                 :             : #include "abi_common.h"
      39                 :             : 
      40                 :             : module m_lattice_langevin_mover
      41                 :             :   use defs_basis
      42                 :             :   use m_abicore
      43                 :             :   use m_errors
      44                 :             : 
      45                 :             :   use m_multibinit_dataset, only: multibinit_dtset_type
      46                 :             :   use m_abstract_potential, only: abstract_potential_t
      47                 :             :   use m_abstract_mover, only: abstract_mover_t
      48                 :             :   use m_lattice_mover, only: lattice_mover_t
      49                 :             :   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      50                 :             :   use m_random_xoroshiro128plus, only:  rng_t
      51                 :             :   use m_hashtable_strval, only: hash_table_t
      52                 :             : !!***
      53                 :             : 
      54                 :             :   implicit none
      55                 :             : 
      56                 :             :   private
      57                 :             : 
      58                 :             :   !-------------------------------------------------------------------!
      59                 :             :   ! Lattice_langevin_mover_t
      60                 :             :   !
      61                 :             :   !-------------------------------------------------------------------!
      62                 :             :   type, public, extends(lattice_mover_t) :: lattice_langevin_mover_t
      63                 :             :      ! c1 to c5 are a constants (temperature and mass dependent)
      64                 :             :      ! c3 c4 c5 has dimension of natom.
      65                 :             :      real(dp) :: c1, c2
      66                 :             :      real(dp), allocatable :: c3(:), c4(:), c5(:)
      67                 :             :      real(dp) :: fr =1e-4 ! friction, usually 1e-2~1e-4
      68                 :             :      ! xi and eta: random numbers of dimension (3, natom)
      69                 :             :      real(dp), allocatable :: xi(:,:), eta(:,:)
      70                 :             :    contains
      71                 :             :      procedure :: initialize
      72                 :             :      procedure :: finalize
      73                 :             :      procedure :: run_one_step
      74                 :             :      procedure :: update_vars
      75                 :             :   end type lattice_langevin_mover_t
      76                 :             : 
      77                 :             : contains
      78                 :             : 
      79                 :             :   !-------------------------------------------------------------------!
      80                 :             :   ! Initialize:
      81                 :             :   !  read parameters
      82                 :             :   !  allocate memory and call update_vars()
      83                 :             :   !-------------------------------------------------------------------!
      84                 :           1 :   subroutine initialize(self,params, supercell, rng)
      85                 :             :     class(lattice_langevin_mover_t), intent(inout) :: self
      86                 :             :     type(multibinit_dtset_type), target, intent(in):: params
      87                 :             :     type(mbsupercell_t), target, intent(in) :: supercell
      88                 :             :     type(rng_t), target, intent(in) :: rng
      89                 :           1 :     call self%lattice_mover_t%initialize(params, supercell, rng)
      90                 :             : 
      91                 :             :     ! TODO: add friction
      92                 :           1 :     self%fr = params%latt_friction
      93                 :             : 
      94   [ -  +  +  -  :           3 :     ABI_MALLOC(self%c3, (self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
      95   [ -  +  +  -  :           3 :     ABI_MALLOC(self%c4, (self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
      96   [ -  +  +  -  :           3 :     ABI_MALLOC(self%c5, (self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
      97   [ -  +  +  -  :           3 :     ABI_MALLOC(self%xi, (3,self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
      98   [ -  +  +  -  :           3 :     ABI_MALLOC(self%eta, (3,self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
      99                 :             : 
     100                 :           1 :     call self%update_vars()
     101                 :           1 :   end subroutine initialize
     102                 :             : 
     103                 :             : 
     104                 :             :   !-------------------------------------------------------------------!
     105                 :             :   ! Finalize
     106                 :             :   !-------------------------------------------------------------------!
     107                 :           1 :   subroutine finalize(self)
     108                 :             :     class(lattice_langevin_mover_t), intent(inout) :: self
     109         [ -  + ]:           1 :     ABI_FREE(self%c3)
     110         [ -  + ]:           1 :     ABI_FREE(self%c4)
     111         [ -  + ]:           1 :     ABI_FREE(self%c5)
     112         [ -  + ]:           1 :     ABI_FREE(self%xi)
     113         [ -  + ]:           1 :     ABI_FREE(self%eta)
     114                 :           1 :     call self%lattice_mover_t%finalize()
     115                 :           1 :   end subroutine finalize
     116                 :             : 
     117                 :             :   !-------------------------------------------------------------------!
     118                 :             :   ! update_vars:
     119                 :             :   !  calculate c1 to c5 from dt, masses and temperature
     120                 :             :   !  It is called by the initialization function.
     121                 :             :   !-------------------------------------------------------------------!
     122                 :           1 :   subroutine update_vars(self)
     123                 :             :     class(lattice_langevin_mover_t), intent(inout) :: self
     124                 :           2 :     real(dp) :: dt, T, fr, sigma(self%natom)
     125                 :             : 
     126                 :           1 :     dt=self%dt
     127                 :           1 :     T= self%temperature
     128                 :           1 :     fr=self%fr
     129         [ +  + ]:         321 :     sigma(:) = sqrt(2.0*T*fr/self%masses(:))
     130                 :           1 :     self%c1 = dt / 2.0 - dt * dt * fr / 8.0
     131                 :           1 :     self%c2 = dt * fr / 2.0 - dt * dt * fr * fr / 8.0
     132   [ +  -  -  +  :         322 :     self%c3 = sqrt(dt) * sigma / 2.0 - dt**1.5 * fr * sigma / 8.0
             -  -  +  + ]
     133   [ +  -  -  +  :         322 :     self%c5 = dt**1.5 * sigma / (2.0 * sqrt(3.0))
             -  -  +  + ]
     134   [ +  -  -  +  :         322 :     self%c4 = fr / 2. * self%c5
             -  -  +  + ]
     135                 :           1 :   end subroutine update_vars
     136                 :             : 
     137                 :             :   !-------------------------------------------------------------------!
     138                 :             :   !> @brief: Run_one_step using a Langevin heat bath.
     139                 :             :   !>   effpot: the potential (which do the calculation of E and dE/dvar)
     140                 :             :   !> param[in]: effpot
     141                 :             :   !> param[in]: (optional) displacement
     142                 :             :   !> param[in]: (optional) strain
     143                 :             :   !> param[in]: (optional) spin
     144                 :             :   !> param[in]: (optional) lwf
     145                 :             :   ! NOTE: No need to pass the variable already saved in the mover.
     146                 :             :   !     e.g. For spin mover, do NOT pass the spin to it.
     147                 :             :   !    The other variables are only required if there is coupling with
     148                 :             :   !    the mover variable.
     149                 :             :   !-------------------------------------------------------------------!
     150   [ -  +  -  -  :          10 :   subroutine run_one_step(self, effpot,displacement, strain, spin, lwf , energy_table)
          -  -  -  +  -  
                -  -  - ]
     151                 :             :     class(lattice_langevin_mover_t), intent(inout) :: self
     152                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     153                 :             :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     154                 :             :     type(hash_table_t), optional, intent(inout) :: energy_table
     155                 :             :     integer :: i
     156                 :             :     character(len=40) :: key
     157                 :             : 
     158                 :             :     ! do not use displacement and strain because they are stored in the mover.
     159                 :          10 :     ABI_UNUSED_A(displacement)
     160                 :          10 :     ABI_UNUSED_A(strain)
     161                 :             : 
     162                 :          10 :     self%energy = 0.0
     163   [ +  +  +  + ]:       12810 :     self%forces(:,:) =0.0
     164                 :             :     call effpot%calculate( displacement=self%displacement, strain=self%strain, &
     165                 :             :          & spin=spin, lwf=lwf, force=self%forces, stress=self%stress, &
     166   [ +  -  +  - ]:          30 :          & energy=self%energy, energy_table=energy_table)
     167                 :          10 :     call self%rng%rand_normal_array(self%xi, 3*self%natom)
     168                 :          10 :     call self%rng%rand_normal_array(self%eta, 3*self%natom)
     169                 :             : 
     170                 :             : 
     171                 :             : 
     172                 :             :     ! First half of velocity update
     173         [ +  + ]:        3210 :     do i =1, self%natom
     174                 :             :        self%current_vcart(:,i) = self%current_vcart(:,i) + &
     175                 :             :             & self%c1 * self%forces(:,i) / self%masses(i) - &
     176                 :             :             & self%c2 * self%current_vcart(:,i) + &
     177         [ +  + ]:       12800 :             & self%c3(i) * self%xi(:, i) - self%c4(i) * self%eta(:,i)
     178                 :             : 
     179                 :             :        self%displacement(:, i) = self%displacement(:, i) &
     180         [ +  + ]:       12810 :             & + self%dt * self%current_vcart(:, i) + self%c5( i) *self%eta(:,i)
     181                 :             :     end do
     182                 :             : 
     183                 :             :     ! second half, update the velocity but not the displacement.
     184                 :          10 :     self%energy=0.0
     185   [ +  +  +  + ]:       12810 :     self%forces=0.0
     186                 :             :     call effpot%calculate( displacement=self%displacement, strain=self%strain, &
     187                 :             :          & spin=spin, lwf=lwf, force=self%forces, stress=self%stress, &
     188   [ +  -  +  - ]:          30 :          & energy=self%energy, energy_table=energy_table)
     189         [ +  + ]:        3210 :     do i =1, self%natom
     190                 :             :        self%current_vcart(:,i) = self%current_vcart(:,i) + &
     191                 :             :             &self%c1 * self%forces(:,i) / self%masses(i) - &
     192                 :             :             & self%c2 * self%current_vcart(:,i) + &
     193         [ +  + ]:       12810 :             & self%c3(i) * self%xi(:, i) - self%c4(i) * self%eta(:,i)
     194                 :             :     end do
     195                 :             : 
     196                 :          10 :     call self%get_T_and_Ek()
     197         [ +  - ]:          10 :     if (present(energy_table)) then
     198                 :          10 :       key = 'Lattice kinetic energy'
     199                 :          10 :        call energy_table%put(key, self%Ek)
     200                 :             :     end if
     201                 :             : 
     202                 :          10 :   end subroutine run_one_step
     203                 :             : 
     204   [ +  +  -  +  :           4 : end module m_lattice_langevin_mover
          +  +  -  +  +  
          +  -  +  -  +  
          +  +  -  +  -  
                +  -  + ]
     205                 :             : 
        

Generated by: LCOV version 2.3-1