LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_pred_hmc.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.6 % 47 44
Test Date: 2026-09-19 15:24:51 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !!****m* ABINIT/m_pred_hmc
       2              : !! NAME
       3              : !!  m_pred_hmc
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2017-2026 ABINIT group (SPr)
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : module m_pred_hmc
      22              : 
      23              :  implicit none
      24              : 
      25              :  private
      26              : !!***
      27              : 
      28              :  public :: pred_hmc
      29              : !!***
      30              : 
      31              : contains
      32              : !!***
      33              : 
      34              : !!****f* ABINIT/pred_hmc
      35              : !! NAME
      36              : !!  pred_hmc
      37              : !!
      38              : !! FUNCTION
      39              : !!  Hybrid Monte Carlo simulation algorithm. The routine generates a markov
      40              : !!  chain of structural configurations (states characterized by ionic positions
      41              : !!  and lattice parameters) with probability of observing a certian state
      42              : !!  equal to Gibbs statistical weight (exp(-etotal/kT)/Z).
      43              : !!
      44              : !! INPUTS
      45              : !!  ab_mover =  Data structure containing information about
      46              : !!              input variables related to MD, e.g dtion, masses, etc.
      47              : !!  hist     =  history of ionic positions, forces,
      48              : !!  itime    =  index of current iteration
      49              : !!  icycle   =  index of current cycle of the iteration
      50              : !!  ntime    =  total number of iterations
      51              : !!  ncycle   =  total number of cycles
      52              : !!  zDEBUG   =  flag indicating whether to print debug info
      53              : !!  iexit    =  flag indicating finilization of mover loop
      54              : !!
      55              : !! OUTPUT
      56              : !!  hist  = ionic positions, lattice parameters etc. are updated
      57              : !!
      58              : !! SIDE EFFECTS
      59              : !!
      60              : !! NOTES
      61              : !!
      62              : !! SOURCE
      63              : 
      64         8014 : subroutine pred_hmc(ab_mover,hist,itime,icycle,ntime,ncycle,mttk_vars,zDEBUG,iexit)
      65              : 
      66              :  use defs_basis
      67              :  use m_errors
      68              :  use m_abicore
      69              :  use m_abimover
      70              :  use m_abihist
      71              :  use m_io_tools
      72              :  use m_hmc
      73              : 
      74              :  use m_geometry,  only : xred2xcart
      75              :  use m_numeric_tools,  only : uniformrandom
      76              :  use m_pred_velverlet,     only : pred_velverlet
      77              :  use m_pred_isothermal,     only : pred_isothermal
      78              : 
      79              : !Arguments ------------------------------------
      80              :  type(abimover),intent(in)   :: ab_mover
      81              :  type(abihist),intent(inout) :: hist
      82              :  type(mttk_type),intent(inout) :: mttk_vars
      83              :  integer,intent(in)          :: itime
      84              :  integer,intent(in)          :: icycle
      85              :  integer,intent(in)          :: ntime
      86              :  integer,intent(in)          :: ncycle
      87              :  integer,intent(in)          :: iexit
      88              :  logical,intent(in)          :: zDEBUG
      89              : 
      90              : !Local variables-------------------------------
      91              :  integer,save  :: seed                                   ! seed for rnd generator
      92              :  integer       :: iacc                                   ! dummy integers for loop indexes and acceptance decision flag
      93              :  real(dp)      :: etotal,epot,ekin,de                    ! total, potential (electronic), kinetic (ionic) energies and energy difference
      94              :  !real(dp)      :: mv2tot,factor                          ! dummies used for rescaling of velocities
      95        16028 :  real(dp)      :: xred(3,ab_mover%natom)                 ! reduced coordinates of all ions
      96        16028 :  real(dp)      :: vel(3,ab_mover%natom)                  ! ionic velocities in Cartesian coordinates
      97              :  !real(dp)      :: mvtot(3)                               ! total momentum of the cell used to rescale velocities
      98              :  real(dp)      :: kbtemp  !mtot,                          ! total ionic mass and target temperature in energy units
      99              :  real(dp)      :: acell(3)                               ! lattice parameters
     100              :  real(dp)      :: rprimd(3,3)                            ! lattice vectors
     101              : 
     102              :  real(dp),save :: etotal_hmc_prev,epot_hmc_prev          ! total energy of the initial state
     103              :  real(dp),save :: strain(3,3),dstrain                    ! strain tensor
     104              :  real(dp),save :: rprimd_original(3,3)                   ! initial lattice vectors <= itime=1,icycle=1
     105              :  real(dp),allocatable,save :: xred_hmc_prev(:,:)         ! reduced coordinates of the ions corresponding to the initial state
     106              :  real(dp),allocatable,save :: fcart_hmc_prev(:,:)        ! reduced coordinates of the ions corresponding to the initial state
     107              : 
     108              :  logical,save  :: strain_updated
     109              :  logical,save  :: xred_updated
     110              :  integer,save  :: strain_steps
     111              :  logical       :: strain_sweep
     112              : 
     113              : ! character(len=500) :: message
     114              : ! *************************************************************************
     115              : 
     116              :  DBG_ENTER("COLL")
     117              : 
     118              : ! if (option/=1 .and. option/=2 ) then
     119              : !   write(msg,'(3a,i0)')&
     120              : !&   'The argument option should be 1 or 2,',ch10,&
     121              : !&   'however, option=',option
     122              : !   ABI_BUG(msg)
     123              : ! end if
     124              : !
     125              : ! if (sizein<1) then
     126              : !   write(msg,'(3a,i0)')&
     127              : !&   'The argument sizein should be a positive number,',ch10,&
     128              : !&   'however, sizein=',sizein
     129              : !   ABI_ERROR(msg)
     130              : ! end if
     131              : 
     132              :  DBG_EXIT("COLL")
     133              : 
     134         8014 :  strain_sweep=.FALSE.
     135              : 
     136         8014 :  if(iexit/=0)then  !icycle=ncycle and itime=ntime
     137            2 :    ABI_SFREE(xred_hmc_prev)
     138            2 :    ABI_SFREE(fcart_hmc_prev)
     139              :    !call pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,1,icycle,ncycle) ! this is needed to deallocate vel_prev array allocated in pred_velverlet
     140            2 :    call pred_isothermal(ab_mover,hist,icycle,mttk_vars,ncycle,zDEBUG,iexit)
     141              :    return
     142              :  end if
     143              : 
     144              : 
     145              :  !get current values of ionic positions and cell geometry and set up the target temperature
     146         8012 :  call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     147              : 
     148     34569932 :  vel(:,:)   = hist%vel(:,:,hist%ihist)                ! velocities of all ions, not needed in reality
     149         8012 :  epot       = hist%etot(hist%ihist)                   ! electronic sub-system energy, not needed
     150         8012 :  ekin       = hist%ekin(hist%ihist)                   ! kinetic energy, not needed
     151              : 
     152         8012 :  kbtemp=(ab_mover%mdtemp(1)+((ab_mover%mdtemp(2)-ab_mover%mdtemp(1))/dble(ntime-1))*(itime-1))*kb_HaK ! correct temperature taking into account the possible heating/cooling
     153              : 
     154         8012 :  if(itime==1.and.icycle==1) then
     155            2 :    ABI_SFREE(xred_hmc_prev)
     156            2 :    ABI_SFREE(fcart_hmc_prev)
     157              : 
     158            6 :    ABI_MALLOC(xred_hmc_prev,(3,ab_mover%natom))
     159            4 :    ABI_MALLOC(fcart_hmc_prev,(3,ab_mover%natom))
     160              : 
     161            2 :    seed=-239
     162              : 
     163            2 :    rprimd_original(:,:)=rprimd(:,:)
     164            2 :    strain(:,:) = 0.0_dp
     165            2 :    strain_steps=0
     166            2 :    dstrain=0.001
     167              : 
     168            2 :    strain_updated=.FALSE.
     169            2 :    xred_updated=.FALSE.
     170              : 
     171            2 :    etotal_hmc_prev = zero
     172            2 :    epot_hmc_prev = zero
     173              : 
     174              :  end if
     175              : 
     176              : 
     177              :  !IN CASE THE SWEEP IS FOR UPDATE OF ATOMIC COORDINATES************************************************
     178              :  !if(.NOT.strain_sweep) then
     179              : 
     180              :    ! *---->*
     181              :    ! 1     n
     182              : 
     183         8012 :  if (icycle==1) then
     184              : 
     185          204 :    if(itime==1) then
     186            2 :      iacc=1
     187            2 :      etotal = epot + ekin
     188            2 :      de=zero
     189              :    else
     190          202 :      etotal = epot + ekin
     191          202 :      de = etotal - etotal_hmc_prev
     192          202 :      call metropolis_check(seed,de,kbtemp,iacc)
     193              : !DEBUG
     194              : !     write(std_out,*)' m_pred_hmc, after metropolis_check : seed,de,kbtemp,iacc=',seed,de,kbtemp,iacc
     195              : !ENDDEBUG
     196              :    end if
     197              : 
     198          204 :    if(iacc==0)then  !in case the new state is not accepted, then roll back the coordinates and energies
     199            0 :      xred(:,:)= xred_hmc_prev(:,:)
     200            0 :      epot     = epot_hmc_prev
     201            0 :      hist%fcart(:,:,hist%ihist) = fcart_hmc_prev(:,:)
     202              :    else
     203       864844 :      xred_hmc_prev(:,:)=xred(:,:)
     204       864844 :      fcart_hmc_prev(:,:) = hist%fcart(:,:,hist%ihist)
     205          204 :      epot_hmc_prev   = epot         !update reference potential energy
     206              :    end if
     207              : 
     208              : !   write(message,'(2a,i7,a,i2,a,E24.16,a,E24.16,a,E24.16)') ch10,' HMC Sweep => ',itime,' iacc= ', iacc,' epot= ',&
     209              : !&   epot,' ekin=',ekin,' de=',de
     210              : !   call wrtout(ab_out,message,'COLL')
     211              : !   call wrtout(std_out,message,'COLL')
     212              : 
     213              :    !call generate_random_velocities(ab_mover,kbtemp,seed,vel,ekin)  ! this routine also computes the new kinetic energy
     214              :    !hist%vel(:,:,hist%ihist)=vel(:,:)
     215       864844 :    hist%vel(:,:,hist%ihist)=0
     216              :    !call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     217              :    !etotal_hmc_prev=epot+ekin ! either old or current potential energy + new kinetic energy
     218              : 
     219              :    !call pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,1,icycle,ncycle) ! 1 is indicating that velverlet is called from hmc routine
     220          204 :    call pred_isothermal(ab_mover,hist,icycle,mttk_vars,ncycle,zDEBUG,iexit)
     221              : 
     222         7808 :  elseif(icycle > 1 .and. icycle <= ncycle)then !icycle/=1
     223              : 
     224              :    !call pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,1,icycle,ncycle) ! 1 is indicating that velverlet is called from hmc routine
     225         7808 :    call pred_isothermal(ab_mover,hist,icycle,mttk_vars,ncycle,zDEBUG,iexit)
     226              : 
     227              :  !end if
     228              :  !END OF ATOMIC COORDINATES SWEEP************************************************
     229              : 
     230              : ! else if(icycle>ncycle) then ! strain update
     231              : !   strain_updated = .TRUE.
     232              : !   strain_steps   = strain_steps + 1
     233              : !! Metropolis update of lattice vectors and parameters in case optcell/=0
     234              : !   if(icycle==ncycle+1.and.xred_updated) then
     235              : !     !save rprimd_hmc_prev and total electronic energy etotal_hmc_prev
     236              : !     call hist2var(acell_hmc_prev,hist,ab_mover%natom,rprimd_hmc_prev,xred,zDEBUG)
     237              : !     etotal_hmc_prev = hist%etot(hist%ihist)
     238              : !     strain_hmc_prev(:,:) = strain(:,:)
     239              : !
     240              : !     select case (ab_mover%optcell)
     241              : !     case (1) !volume optimization only
     242              : !       acell(:)=acell(:)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     243              : !     case (2,3,7,8,9) !full geometry optimization
     244              : !       !suggest new strain tensor values
     245              : !       do ii=1,3
     246              : !         do jj=ii,3
     247              : !           strain(ii,jj) = strain(ii,jj)+ 2.0_dp*dstrain*(uniformrandom(seed)-0.5_dp)
     248              : !           strain(jj,ii) = strain(ii,jj)
     249              : !         enddo
     250              : !       enddo
     251              : !       if(ab_mover%optcell==3) then !eliminate volume change if optcell==3
     252              : !         do ii=1,3
     253              : !           strain(ii,ii) = strain(ii,ii) -(strain(1,1)+strain(2,2)+strain(3,3))
     254              : !         enddo
     255              : !       endif
     256              : !       do jj=1,3    ! sum over three lattice vectors
     257              : !         do ii=1,3  ! sum over Cart components
     258              : !           rprimd(ii,jj)=rprimd_original(ii,jj)+&
     259              : !&                        rprimd_original(1,jj)*strain(ii,1)+&
     260              : !&                        rprimd_original(2,jj)*strain(ii,2)+&
     261              : !&                        rprimd_original(3,jj)*strain(ii,3)
     262              : !         enddo
     263              : !       enddo
     264              : !       if(ab_mover%optcell==7) then
     265              : !         rprimd(:,1)=rprimd_original(:,1)
     266              : !       else if (ab_mover%optcell==8) then
     267              : !         rprimd(:,2)=rprimd_original(:,2)
     268              : !       else if (ab_mover%optcell==9) then
     269              : !         rprimd(:,3)=rprimd_original(:,3)
     270              : !       endif
     271              : !     case(4)
     272              : !       acell(1)=acell(1)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     273              : !     case(5)
     274              : !       acell(2)=acell(2)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     275              : !     case(6)
     276              : !       acell(3)=acell(3)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     277              : !     !case default
     278              : !     !  write(message,"(a,i0)") "Wrong value of optcell: ",ab_mover%optcell
     279              : !     !  ABI_ERROR(message)
     280              : !     end select
     281              : !
     282              : !     !update the new suggested rprimd and or acell in the history record
     283              : !     hist%ihist=abihist_findIndex(hist,+1)
     284              : !     call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     285              : !   else
     286              : !
     287              : !     etotal = hist%etot(hist%ihist)
     288              : !     de = etotal - etotal_hmc_prev
     289              : !
     290              : !     iacc=0
     291              : !     rnd=uniformrandom(seed)
     292              : !     if(de<0)then
     293              : !       iacc=1
     294              : !     else
     295              : !       if(exp(-de/kbtemp)>rnd)then
     296              : !         iacc=1
     297              : !       end if
     298              : !     end if
     299              : !
     300              : !     if(iacc==0) then
     301              : !      strain(:,:)=strain_hmc_prev(:,:)
     302              : !      acell(:)=acell_hmc_prev(:)
     303              : !     else
     304              : !      call hist2var(acell_hmc_prev,hist,ab_mover%natom,rprimd_hmc_prev,xred,zDEBUG)
     305              : !      strain_hmc_prev(:,:) = strain(:,:)
     306              : !      etotal_hmc_prev=etotal
     307              : !     endif
     308              : !
     309              : !    !suggest new acell/rprimd values depending on the optcell value
     310              : !     select case (ab_mover%optcell)
     311              : !     case (1) !volume optimization only
     312              : !       acell(:)=acell(:)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     313              : !     case (2,3,7,8,9) !full geometry optimization
     314              : !       !suggest new strain tensor values
     315              : !       do ii=1,3
     316              : !         do jj=ii,3
     317              : !           strain(ii,jj) = strain(ii,jj)+ 2.0_dp*dstrain*(uniformrandom(seed)-0.5_dp)
     318              : !           strain(jj,ii) = strain(ii,jj)
     319              : !         enddo
     320              : !       enddo
     321              : !       if(ab_mover%optcell==3) then !eliminate volume change if optcell==3
     322              : !         do ii=1,3
     323              : !           strain(ii,ii) = strain(ii,ii) -(strain(1,1)+strain(2,2)+strain(3,3))
     324              : !         enddo
     325              : !       endif
     326              : !       do jj=1,3    ! sum over three lattice vectors
     327              : !         do ii=1,3  ! sum over Cart components
     328              : !           rprimd(ii,jj)=rprimd_original(ii,jj)+&
     329              : !&                        rprimd_original(1,jj)*strain(ii,1)+&
     330              : !&                        rprimd_original(2,jj)*strain(ii,2)+&
     331              : !&                        rprimd_original(3,jj)*strain(ii,3)
     332              : !         enddo
     333              : !       enddo
     334              : !       if(ab_mover%optcell==7) then
     335              : !         rprimd(:,1)=rprimd_original(:,1)
     336              : !       else if (ab_mover%optcell==8) then
     337              : !         rprimd(:,2)=rprimd_original(:,2)
     338              : !       else if (ab_mover%optcell==9) then
     339              : !         rprimd(:,3)=rprimd_original(:,3)
     340              : !       endif
     341              : !     case(4)
     342              : !       acell(1)=acell(1)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     343              : !     case(5)
     344              : !       acell(2)=acell(2)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     345              : !     case(6)
     346              : !       acell(3)=acell(3)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
     347              : !     case default
     348              : !     !  write(message,"(a,i0)") "Wrong value of optcell: ",ab_mover%optcell
     349              : !     !  ABI_ERROR(message)
     350              : !     end select
     351              : !
     352              : !     !update the new suggested rprimd/acell in the history record
     353              : !     hist%ihist=abihist_findIndex(hist,+1)
     354              : !     call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     355              : !
     356              : !   endif
     357              : 
     358              :  end if
     359              : 
     360         8014 : end subroutine pred_hmc
     361              : !!***
     362              : 
     363              : end module m_pred_hmc
     364              : !!***
        

Generated by: LCOV version 2.3-1