LCOV - code coverage report
Current view: top level - src/78_effpot - m_lwf_mc_mover.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 65 0
Test Date: 2026-11-12 14:41:44 Functions: 0.0 % 10 0
Branches: 0.0 % 64 0

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_lwf_mc_mover
       2                 :             : !! NAME
       3                 :             : !! m_lwf_mc_mover
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module contains the lwf Markov chain Monte Carlo functions for lwf mover .
       7                 :             : !!
       8                 :             : !!
       9                 :             : !! Datatypes:
      10                 :             : !!
      11                 :             : !! * lwf_mc_t : MCMC. It defines how to move lwfs in one step,
      12                 :             : !! attempt function: whether to accept move
      13                 :             : !! accecpt/reject method which define what to do if move is
      14                 :             : !! accepted or rejected!! .
      15                 :             : !!
      16                 :             : !! Subroutines:
      17                 :             : !! TODO: add this when F2003 doc style is determined.
      18                 :             : !!
      19                 :             : !!
      20                 :             : !! COPYRIGHT
      21                 :             : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      22                 :             : !! This file is distributed under the terms of the
      23                 :             : !! GNU General Public License, see ~abinit/COPYING
      24                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      25                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      26                 :             : !!
      27                 :             : !! SOURCE
      28                 :             : 
      29                 :             : #if defined HAVE_CONFIG_H
      30                 :             : #include "config.h"
      31                 :             : #endif
      32                 :             : #include "abi_common.h"
      33                 :             :     module m_lwf_mc_mover
      34                 :             :     use defs_basis
      35                 :             :     use m_abicore
      36                 :             :     use m_errors
      37                 :             :     use m_abstract_potential, only: abstract_potential_t
      38                 :             :     use m_random_xoroshiro128plus, only: rng_t
      39                 :             :     use m_hashtable_strval, only: hash_table_t
      40                 :             :     use m_multibinit_dataset, only: multibinit_dtset_type
      41                 :             :     use m_lwf_mover, only: lwf_mover_t
      42                 :             :     use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      43                 :             :     implicit none
      44                 :             : !!***
      45                 :             :     private
      46                 :             : 
      47                 :             :     !----------------------------------------------------------------------
      48                 :             :     !> @brief An helper type to run lwf dynamics
      49                 :             :     ! The Metropolis-Hasting algorithm is used.
      50                 :             :     !----------------------------------------------------------------------
      51                 :             :     type,public, extends(lwf_mover_t) :: lwf_mc_t
      52                 :             :        real(dp) :: avg_amp! an angle to rotate by average
      53                 :             :        real(dp) ::  deltaE ! energy and the change of energy when change one lwf
      54                 :             :        real(dp) :: lwf_new, lwf_old! energy and the change of energy when change one lwf
      55                 :             :        real(dp) :: beta  ! 1/(kb T)
      56                 :             :        integer :: nstep  ! number of steps
      57                 :             :        integer :: imove ! index of lwf to be moved
      58                 :             :        integer :: naccept  ! number of accepted steps
      59                 :             :        integer :: nattempt
      60                 :             :      contains
      61                 :             :        procedure :: initialize
      62                 :             :        procedure :: finalize
      63                 :             :        procedure, private :: attempt
      64                 :             :        procedure, private :: accept
      65                 :             :        procedure, private :: reject
      66                 :             :        procedure  :: run_one_step
      67                 :             :        procedure :: set_temperature
      68                 :             :        procedure, private :: run_one_mc_step
      69                 :             :     end type lwf_mc_t
      70                 :             : 
      71                 :             : 
      72                 :             :   contains
      73                 :             : 
      74                 :           0 :     subroutine initialize(self, params, supercell, rng)
      75                 :             :       class(lwf_mc_t), intent(inout) :: self
      76                 :             :       type(multibinit_dtset_type),target, intent(in) :: params
      77                 :             :       type(mbsupercell_t),target, intent(in) :: supercell
      78                 :             :       type(rng_t), target, intent(in) :: rng
      79                 :           0 :       call self%lwf_mover_t%initialize(params, supercell, rng)
      80                 :           0 :       self%nstep=self%nlwf
      81                 :           0 :       self%avg_amp=params%lwf_mc_avg_amp
      82                 :           0 :       self%temperature=params%lwf_temperature
      83                 :           0 :       self%beta=1.0/self%temperature ! Kb in a.u. is 1.
      84                 :           0 :       self%lwf_new=0.0_dp
      85                 :           0 :       self%lwf_old=0.0_dp
      86                 :           0 :       self%nattempt=0
      87                 :           0 :       self%naccept=0
      88                 :           0 :     end subroutine initialize
      89                 :             : 
      90                 :             :     !----------------------------------------------------------------------
      91                 :             :     !> @brief finalize
      92                 :             :     !----------------------------------------------------------------------
      93                 :           0 :     subroutine finalize(self)
      94                 :             :       class(lwf_mc_t), intent(inout) :: self
      95                 :           0 :       call self%lwf_mover_t%finalize()
      96                 :           0 :       self%nstep=0
      97                 :           0 :       self%avg_amp=0.0
      98                 :           0 :       self%temperature=0.0
      99                 :           0 :       self%beta=0.0
     100                 :           0 :     end subroutine finalize
     101                 :             : 
     102                 :           0 :     subroutine set_temperature(self, temperature)
     103                 :             :       class(lwf_mc_t), intent(inout) :: self
     104                 :             :       real(dp), intent(in) :: temperature
     105                 :           0 :       call self%lwf_mover_t%set_temperature(temperature)
     106                 :           0 :       self%temperature=temperature
     107                 :           0 :       self%beta=1.0/self%temperature ! Kb in a.u. is 1.
     108                 :           0 :     end subroutine set_temperature
     109                 :             : 
     110                 :             : 
     111                 :             :     !----------------------------------------------------------------------
     112                 :             :     !> @brief run one monte carlo step
     113                 :             :     !> @param[in]   rngL rundom number generator
     114                 :             :     !> @param[in] effpot: effective lwf potential
     115                 :             :     !----------------------------------------------------------------------
     116                 :           0 :    subroutine run_one_mc_step(self,  effpot)
     117                 :             :      class(lwf_mc_t) :: self
     118                 :             :      class(abstract_potential_t), intent(inout) :: effpot
     119                 :             :      real(dp) :: r
     120                 :             : 
     121                 :             :      ! try to change lwf
     122                 :           0 :      r=self%attempt(self%rng, effpot)
     123                 :             :      ! metropolis-hastings
     124                 :           0 :      self%nattempt=self%nattempt+1
     125   [ #  #  #  # ]:           0 :      if(self%rng%rand_unif_01()< min(1.0_dp, r) .and. abs(self%lwf_new)<0.5 ) then
     126                 :           0 :         self%naccept=self%naccept+1
     127                 :           0 :         call self%accept()
     128                 :             :      else
     129                 :           0 :         call self%reject()
     130                 :             :      end if
     131                 :           0 :    end subroutine run_one_mc_step
     132                 :             : 
     133                 :             : 
     134                 :             :   !-------------------------------------------------------------------!
     135                 :             :   !> @brief: Run_one_step
     136                 :             :   !>   effpot: the potential (which do the calculation of E and dE/dvar)
     137                 :             :   !> param[in]: effpot
     138                 :             :   !> param[in]: (optional) displacement
     139                 :             :   !> param[in]: (optional) strain
     140                 :             :   !> param[in]: (optional) spin
     141                 :             :   !> param[in]: (optional) lwf
     142                 :             :   ! NOTE: No need to pass the variable already saved in the mover.
     143                 :             :   !     e.g. For spin mover, do NOT pass the spin to it.
     144                 :             :   !    The other variables are only required if there is coupling with
     145                 :             :   !    the mover variable.
     146                 :             :   !-------------------------------------------------------------------!
     147   [ #  #  #  #  :           0 :   subroutine run_one_step(self, effpot, displacement, strain, spin, lwf,  energy_table)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     148                 :             :     ! run one step. (For MC also?)
     149                 :             :     class(lwf_mc_t), intent(inout) :: self
     150                 :             :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     151                 :             :     type(hash_table_t), optional, intent(inout) :: energy_table
     152                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     153                 :             :     integer :: i
     154                 :             :     character(len=40) :: key
     155                 :             : 
     156                 :           0 :     ABI_UNUSED_A(displacement)
     157                 :           0 :     ABI_UNUSED_A(strain)
     158                 :           0 :     ABI_UNUSED_A(spin)
     159                 :             : 
     160                 :             :     !self%lwf(:)=lwf(:)
     161         [ #  # ]:           0 :     self%lwf_force(:) = 0.0_dp
     162                 :             :     ! calculate energy at first step
     163                 :           0 :     self%energy=0.0
     164                 :             : 
     165                 :             : 
     166                 :             :     call effpot%calculate( displacement=displacement, strain=strain, &
     167                 :             :          & spin=spin, lwf=self%lwf, lwf_force=self%lwf_force, &
     168   [ #  #  #  #  :           0 :          & energy=self%energy, energy_table=energy_table)
                   #  # ]
     169                 :             :     !print *, "Calculated energy", self%energy/self%supercell%ncell
     170                 :             : 
     171         [ #  # ]:           0 :     do i = 1, self%nstep
     172                 :           0 :        call self%run_one_mc_step(effpot)
     173                 :             :     end do
     174                 :             :     !print *, "Calculated MC energy", self%energy/self%supercell%ncell
     175                 :             :     !print *, "Accept rate:", (1.0_dp*self%naccept)/self%nattempt
     176         [ #  # ]:           0 :     lwf(:)=self%lwf(:)
     177         [ #  # ]:           0 :     if (present(energy_table)) then
     178                 :           0 :        key = 'LWF energy'
     179                 :           0 :        call energy_table%put(key, self%energy)
     180                 :             :     end if
     181                 :             : 
     182                 :           0 :   end subroutine run_one_step
     183                 :             : 
     184                 :             : 
     185                 :             :    !----------------------------------------------------------------------
     186                 :             :    !> @brief accept the trail step, which update the lwf and energy
     187                 :             :    !----------------------------------------------------------------------
     188                 :           0 :    subroutine accept(self)
     189                 :             :      class(lwf_mc_t), intent(inout) :: self
     190                 :           0 :      self%lwf(self%imove)=self%lwf_new
     191                 :           0 :      self%energy=self%energy+self%deltaE
     192                 :             :      !print *, "E:", self%energy/self%supercell%ncell
     193                 :           0 :    end subroutine accept
     194                 :             : 
     195                 :             :    !----------------------------------------------------------------------
     196                 :             :    !> @brief reject the trail step, changes nothing.
     197                 :             :    !----------------------------------------------------------------------
     198                 :           0 :    subroutine reject(self)
     199                 :             :      class(lwf_mc_t), intent(inout) :: self
     200                 :             :      ! do nothing.
     201                 :           0 :      ABI_UNUSED_A(self)
     202                 :           0 :    end subroutine reject
     203                 :             : 
     204                 :             :    !----------------------------------------------------------------------
     205                 :             :    !> @brief define a trail step  using Hinzke_nowak method and calculate energy difference
     206                 :             :    !----------------------------------------------------------------------
     207                 :           0 :    function attempt(self,rng, effpot) result(r)
     208                 :             :      class(lwf_mc_t) :: self
     209                 :             :      class(rng_t) :: rng
     210                 :             :      class(abstract_potential_t), intent(inout) :: effpot
     211                 :             :      real(dp) :: r
     212                 :             :      ! choose one site
     213                 :           0 :      self%imove = rng%rand_choice(self%nlwf)
     214                 :           0 :      self%lwf_old= self%lwf(self%imove)
     215                 :           0 :      self%deltaE=0.0
     216                 :           0 :      call move(rng, self%lwf_old, self%lwf_new, self%avg_amp)
     217                 :           0 :      call effpot%get_delta_E_lwf( self%lwf, self%imove, self%lwf_new, self%deltaE)
     218                 :           0 :      r=exp(-self%deltaE *self%beta)
     219                 :           0 :    end function attempt
     220                 :             : 
     221                 :             :    !----------------------------------------------------------------------
     222                 :             :    !> @brief add to lwf by a random value.
     223                 :             :    !----------------------------------------------------------------------
     224                 :           0 :    subroutine move(rng, lwf_old, lwf_new, avg_amp)
     225                 :             :      type(rng_t) :: rng
     226                 :             :      real(dp), intent(in) :: lwf_old, avg_amp
     227                 :             :      real(dp), intent(out) :: lwf_new
     228                 :             :      real(dp):: dlwf
     229                 :           0 :      dlwf=rng%rand_normal()
     230                 :           0 :      lwf_new=lwf_old + dlwf*avg_amp
     231                 :           0 :    end subroutine move
     232                 :             : 
     233   [ #  #  #  #  :           0 : end module m_lwf_mc_mover
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
        

Generated by: LCOV version 2.3-1