LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_pred_langevin.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 48.3 % 265 128
Test Date: 2026-11-11 08:14:47 Functions: 100.0 % 1 1
Branches: 51.8 % 338 175

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_pred_langevin
       2                 :             : !! NAME
       3                 :             : !!  m_pred_langevin
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! COPYRIGHT
       8                 :             : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, JCC, SE)
       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_langevin
      22                 :             : 
      23                 :             :  use defs_basis
      24                 :             :  use m_abicore
      25                 :             :  use m_abimover
      26                 :             :  use m_abihist
      27                 :             : 
      28                 :             :  use m_numeric_tools,  only : uniformrandom
      29                 :             :  use m_geometry,    only : xcart2xred, xred2xcart, metric
      30                 :             :  use m_results_gs , only : results_gs_type
      31                 :             : 
      32                 :             :  implicit none
      33                 :             : 
      34                 :             :  private
      35                 :             : !!***
      36                 :             : 
      37                 :             :  public :: pred_langevin
      38                 :             : !!***
      39                 :             : 
      40                 :             : contains
      41                 :             : !!***
      42                 :             : 
      43                 :             : !!****f* ABINIT/pred_langevin
      44                 :             : !! NAME
      45                 :             : !! pred_langevin
      46                 :             : !!
      47                 :             : !! FUNCTION
      48                 :             : !! Ionmov predictors (9) Langevin dynamics algorithm
      49                 :             : !!
      50                 :             : !! IONMOV 9:
      51                 :             : !! Uses a Langevin dynamics algorithm :
      52                 :             : !! see J. Chelikowsky, J. Phys. D : Appl Phys. 33(2000)R33 [[cite:Chelikowsky2000]]
      53                 :             : !!
      54                 :             : !! INPUTS
      55                 :             : !! ab_mover <type(abimover)> : Datatype with all the information
      56                 :             : !!                                needed by the preditor
      57                 :             : !! itime  : Index of the present iteration
      58                 :             : !! ntime  : Maximal number of iterations
      59                 :             : !! icycle : Index of the present cycle
      60                 :             : !! ncycle : Maximal number of cycles
      61                 :             : !! zDEBUG : if true print some debugging information
      62                 :             : !!
      63                 :             : !! OUTPUT
      64                 :             : !!
      65                 :             : !! SIDE EFFECTS
      66                 :             : !! hist <type(abihist)> : History of positions,forces acell, rprimd, stresses
      67                 :             : !!
      68                 :             : !! SOURCE
      69                 :             : 
      70                 :          20 : subroutine pred_langevin(ab_mover,hist,icycle,itime,ncycle,ntime,zDEBUG,iexit,skipcycle)
      71                 :             : 
      72                 :             : !Arguments ------------------------------------
      73                 :             : !scalars
      74                 :             :  type(abimover),intent(in)       :: ab_mover
      75                 :             :  type(abihist),intent(inout) :: hist
      76                 :             :  integer,intent(in)    :: itime
      77                 :             :  integer,intent(in)    :: ntime
      78                 :             :  integer,intent(in)    :: iexit
      79                 :             :  integer,intent(in)    :: icycle
      80                 :             :  integer,intent(inout) :: ncycle
      81                 :             :  logical,intent(in)    :: zDEBUG
      82                 :             :  logical,intent(out)   :: skipcycle
      83                 :             : 
      84                 :             : !Local variables-------------------------------
      85                 :             : !scalars
      86                 :             :  integer  :: ii,kk,iatom,idim,iatom1,iatom2,itypat,idum=5,ihist_prev,mcfac
      87                 :             :  real(dp) :: ucvol,ucvol_next
      88                 :             :  real(dp),parameter :: v2tol=tol8
      89                 :             :  real(dp) :: etotal,rescale_vel,ran_num1,ran_num2
      90                 :             :  real(dp) :: ktemp,dist,distx,disty,distz,maxp1,maxp2,v2nose
      91                 :             :  real(dp) :: sig_gauss,delxi
      92                 :             :  logical  :: jump_end_of_cycle=.FALSE.
      93                 :             :  character(len=5000) :: message
      94                 :             : !arrays
      95                 :          20 :  integer,allocatable :: imax_perm(:)
      96                 :             :  real(dp),allocatable,save :: max_perm(:),pot_perm(:)
      97                 :             :  real(dp),allocatable,save :: ran_force(:,:),lang_force(:,:)
      98                 :             :  real(dp),allocatable,save :: fcart_mold(:,:),fcart_m(:,:)
      99                 :             : 
     100                 :             :  real(dp) :: acell(3),acell_next(3)
     101                 :             :  real(dp) :: rprim(3,3),rprimd(3,3),rprimd_next(3,3),rprim_next(3,3)
     102                 :             :  real(dp) :: gprimd(3,3),gmet(3,3),rmet(3,3)
     103                 :          40 :  real(dp) :: fcart(3,ab_mover%natom)
     104                 :          40 :  real(dp) :: xcart(3,ab_mover%natom),xcart_next(3,ab_mover%natom)
     105                 :          40 :  real(dp) :: xred(3,ab_mover%natom),xred_next(3,ab_mover%natom)
     106                 :          20 :  real(dp) :: vel(3,ab_mover%natom)
     107                 :             :  real(dp) :: strten(6)
     108                 :             : 
     109                 :             : !***************************************************************************
     110                 :             : !Beginning of executable session
     111                 :             : !***************************************************************************
     112                 :             : 
     113         [ +  + ]:          20 :  if(iexit/=0)then
     114         [ +  - ]:           2 :    ABI_SFREE(pot_perm)
     115         [ +  - ]:           2 :    ABI_SFREE(max_perm)
     116                 :             :    ABI_SFREE(imax_perm)
     117         [ +  - ]:           2 :    ABI_SFREE(ran_force)
     118         [ +  - ]:           2 :    ABI_SFREE(lang_force)
     119         [ +  - ]:           2 :    ABI_SFREE(fcart_mold)
     120         [ +  - ]:           2 :    ABI_SFREE(fcart_m)
     121                 :             :    return
     122                 :             :  end if
     123                 :             : 
     124                 :          18 :  jump_end_of_cycle=.FALSE.
     125                 :             : 
     126                 :             : !write(std_out,*) 'langevin 02',jump_end_of_cycle
     127                 :             : !##########################################################
     128                 :             : !### 02. Allocate the arrays
     129                 :             : !###     These arrays could be allocated from a previus
     130                 :             : !###     dataset that exit before itime==ntime
     131                 :             : 
     132         [ +  + ]:          18 :  if(itime==1)then
     133         [ -  + ]:           2 :    ABI_SFREE(pot_perm)
     134         [ -  + ]:           2 :    ABI_SFREE(max_perm)
     135                 :             :    ABI_SFREE(imax_perm)
     136         [ -  + ]:           2 :    ABI_SFREE(ran_force)
     137         [ -  + ]:           2 :    ABI_SFREE(lang_force)
     138         [ -  + ]:           2 :    ABI_SFREE(fcart_mold)
     139         [ -  + ]:           2 :    ABI_SFREE(fcart_m)
     140                 :             :  end if
     141                 :             : 
     142         [ +  + ]:          18 :  if (.not.allocated(pot_perm))    then
     143   [ -  +  +  -  :           6 :    ABI_MALLOC(pot_perm,(ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     144                 :             :  end if
     145         [ +  + ]:          18 :  if (.not.allocated(max_perm))    then
     146   [ -  +  +  -  :           6 :    ABI_MALLOC(max_perm,(ab_mover%ntypat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     147                 :             :  end if
     148                 :             :  if (.not.allocated(imax_perm))   then
     149   [ -  +  +  -  :          54 :    ABI_MALLOC(imax_perm,(ab_mover%ntypat))
          +  -  +  -  -  
                +  -  + ]
     150                 :             :  end if
     151         [ +  + ]:          18 :  if (.not.allocated(ran_force))   then
     152   [ -  +  +  -  :           6 :    ABI_MALLOC(ran_force,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     153                 :             :  end if
     154         [ +  + ]:          18 :  if (.not.allocated(lang_force))  then
     155   [ -  +  +  -  :           6 :    ABI_MALLOC(lang_force,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     156                 :             :  end if
     157         [ +  + ]:          18 :  if (.not.allocated(fcart_mold))  then
     158   [ -  +  +  -  :           6 :    ABI_MALLOC(fcart_mold,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     159                 :             :  end if
     160         [ +  + ]:          18 :  if (.not.allocated(fcart_m))     then
     161   [ -  +  +  -  :           6 :    ABI_MALLOC(fcart_m,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     162                 :             :  end if
     163                 :             : 
     164                 :             : !write(std_out,*) 'langevin 03',jump_end_of_cycle
     165                 :             : !##########################################################
     166                 :             : !### 03. Obtain the present values from the history
     167                 :             : 
     168                 :          18 :  call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     169                 :             : 
     170   [ +  +  +  + ]:         198 :  fcart(:,:)=hist%fcart(:,:,hist%ihist)
     171         [ +  + ]:         126 :  strten(:) =hist%strten(:,hist%ihist)
     172   [ +  +  +  + ]:         198 :  vel(:,:)  =hist%vel(:,:,hist%ihist)
     173                 :          18 :  etotal    =hist%etot(hist%ihist)
     174                 :             : 
     175                 :          18 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     176         [ +  + ]:          72 :  do ii=1,3
     177         [ +  + ]:         234 :    rprim(ii,1:3)=rprimd(ii,1:3)/acell(1:3)
     178                 :             :  end do
     179                 :          18 :  call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
     180                 :             : 
     181                 :             : !write(std_out,*) 'langevin 04',jump_end_of_cycle
     182                 :             : !##########################################################
     183                 :             : !### 04. Compute the next values (Only for the first cycle)
     184                 :             : 
     185         [ +  - ]:          18 :  if (icycle==1) then
     186                 :             : 
     187                 :             : !  The temperature is linear between initial and final values
     188                 :             : !  It is here converted from Kelvin to Hartree (kb_HaK)
     189                 :          18 :    ktemp=(ab_mover%mdtemp(1)+((ab_mover%mdtemp(2)-ab_mover%mdtemp(1))/dble(ntime-1))*(itime-1))*kb_HaK
     190                 :             : !  write(std_out,*) 'KTEMP=',ktemp
     191                 :             : !  write(std_out,*) 'MDITEMP=',ab_mover%mdtemp(1)
     192                 :             : !  write(std_out,*) 'MDFTEMP=',ab_mover%mdtemp(2)
     193                 :             : !  write(std_out,*) 'DELAYPERM=',ab_mover%delayperm
     194                 :             : 
     195                 :             : 
     196                 :             : !  %%% LANGEVIN DYNAMICS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     197                 :             : 
     198                 :             : !  1. Next values are the present ones
     199                 :          18 :    acell_next(:)=acell(:)
     200                 :          18 :    ucvol_next=ucvol
     201                 :          18 :    rprim_next(:,:)=rprim(:,:)
     202                 :          18 :    rprimd_next(:,:)=rprimd(:,:)
     203                 :             : 
     204         [ -  + ]:          18 :    if (zDEBUG) then
     205                 :           0 :      write (std_out,*) '1. Next values are the present ones'
     206                 :           0 :      write(std_out,*) 'RPRIMD'
     207         [ #  # ]:           0 :      do kk=1,3
     208                 :           0 :        write(std_out,*) rprimd(:,kk)
     209                 :             :      end do
     210                 :           0 :      write(std_out,*) 'RPRIM'
     211         [ #  # ]:           0 :      do kk=1,3
     212                 :           0 :        write(std_out,*) rprim(:,kk)
     213                 :             :      end do
     214                 :           0 :      write(std_out,*) 'ACELL'
     215                 :           0 :      write(std_out,*) acell(:)
     216                 :             :    end if
     217                 :             : 
     218         [ +  + ]:          18 :    if(itime==1)then
     219                 :             : 
     220                 :             : !    2.   Compute twice the kinetic energy of the system, called v2nose
     221                 :           2 :      v2nose=0.0_dp
     222         [ +  + ]:           7 :      do iatom=1,ab_mover%natom
     223         [ +  + ]:          22 :        do idim=1,3
     224                 :          20 :          v2nose=v2nose+vel(idim,iatom)*vel(idim,iatom)*ab_mover%amass(iatom)
     225                 :             :        end do
     226                 :             :      end do
     227         [ -  + ]:           2 :      if (zDEBUG) then
     228                 :           0 :        write (std_out,*) '2.   Compute twice the kinetic energy of the system, called v2nose'
     229                 :           0 :        write (std_out,*) 'V2NOSE=',v2nose
     230                 :             :      end if
     231                 :             : 
     232                 :             : !    3.   If there is no kinetic energy, use random numbers
     233         [ +  - ]:           2 :      if (v2nose<=v2tol) then
     234                 :           2 :        v2nose=0.0_dp
     235         [ +  + ]:           7 :        do iatom=1,ab_mover%natom
     236         [ +  + ]:          22 :          do idim=1,3
     237                 :             : !          uniformrandom returns a uniform random deviate between 0.0 and 1.0
     238                 :             : !          if it were always 0 or 1, then the following expression
     239                 :             : !          would give the requested temperature
     240                 :          15 :            vel(idim,iatom)=(1.0_dp-2.0_dp*uniformrandom(idum))*sqrt(ktemp/ab_mover%amass(iatom))
     241                 :             : !          Recompute v2nose
     242                 :          20 :            v2nose=v2nose+vel(idim,iatom)*vel(idim,iatom)*ab_mover%amass(iatom)
     243                 :             :          end do
     244                 :             :        end do
     245                 :             :      end if
     246                 :             : 
     247         [ -  + ]:           2 :      if (zDEBUG) then
     248                 :           0 :        write (std_out,*) '3.   If there is no kinetic energy, use random numbers'
     249                 :           0 :        write (std_out,*) 'VEL'
     250         [ #  # ]:           0 :        do kk=1,ab_mover%natom
     251                 :           0 :          write (std_out,*) vel(:,kk)
     252                 :             :        end do
     253                 :           0 :        write (std_out,*) 'V2NOSE=',v2nose
     254                 :             :      end if
     255                 :             : 
     256                 :             : 
     257                 :             : !    Now, rescale the velocities to give the proper temperature
     258                 :           2 :      rescale_vel=sqrt(3.0_dp*ab_mover%natom*(ab_mover%mdtemp(1))*kb_HaK/v2nose)
     259   [ +  +  +  + ]:          22 :      vel(:,:)=vel(:,:)*rescale_vel
     260                 :             : !    Recompute v2nose with the rescaled velocities
     261                 :           2 :      v2nose=0.0_dp
     262         [ +  + ]:           7 :      do iatom=1,ab_mover%natom
     263         [ +  + ]:          22 :        do idim=1,3
     264                 :          20 :          v2nose=v2nose+vel(idim,iatom)*vel(idim,iatom)*ab_mover%amass(iatom)
     265                 :             :        end do
     266                 :             :      end do
     267                 :             :      write(message, '(a)' )&
     268                 :           2 : &     ' Rescaling or initializing velocities to initial temperature'
     269                 :           2 :      call wrtout(ab_out,message,'COLL')
     270                 :           2 :      call wrtout(std_out,message,'COLL')
     271                 :             :      write(message, '(a,D12.5,a,D12.5)' )&
     272                 :           2 : &     ' ---  Scaling factor : ',rescale_vel,' Asked T (K) ',ab_mover%mdtemp(1)
     273                 :           2 :      call wrtout(ab_out,message,'COLL')
     274                 :           2 :      call wrtout(std_out,message,'COLL')
     275                 :             :      write(message, '(a,D12.5)' )&
     276                 :           2 : &     ' ---  Effective temperature',v2nose/3.0_dp/(kb_HaK*ab_mover%natom)
     277                 :           2 :      call wrtout(ab_out,message,'COLL')
     278                 :           2 :      call wrtout(std_out,message,'COLL')
     279                 :             : !    end if itime==0
     280                 :             :    end if
     281                 :             : 
     282                 :             : !  This section is devoted to the optional atom permutation (JYR 001114)
     283                 :             : !  Two input variables are needed
     284                 :             : !  ab_mover%delayperm : is the interval (in time steps) at which
     285                 :             : !  atoms are tentatively permuted
     286                 :             : !  default value could be 0
     287                 :             : !  ab_mover%signperm  : is the type of bias for the permutation
     288                 :             : !  +1  to favor alternation of species
     289                 :             : !  -1  to favor segregation
     290                 :             : 
     291                 :             : !  Force no permutation at initial step
     292   [ +  +  +  -  :          18 :    if (itime/=1 .and. ab_mover%delayperm/=0 .and. ab_mover%ntypat>2) then
                   -  + ]
     293         [ #  # ]:           0 :      if (mod(itime-1,ab_mover%delayperm)==0) then
     294                 :             : !      Try commutation of atoms.
     295                 :           0 :        write(message, '(a)')' Attempt of commutation '
     296                 :           0 :        call wrtout(ab_out,message,'COLL')
     297                 :           0 :        call wrtout(std_out,message,'COLL')
     298                 :             : !      Compute a 'permutation potential'
     299         [ #  # ]:           0 :        do iatom=1,ab_mover%natom
     300                 :           0 :          pot_perm(iatom)=0.0_dp
     301         [ #  # ]:           0 :          do iatom1=1,ab_mover%natom
     302         [ #  # ]:           0 :            if (iatom1.ne.iatom) then
     303                 :           0 :              distx=xcart(1,iatom)-xcart(1,iatom1)
     304                 :           0 :              distx=distx-acell(1)*nint(distx/acell(1))
     305                 :           0 :              disty=xcart(2,iatom)-xcart(2,iatom1)
     306                 :           0 :              disty=disty-acell(2)*nint(disty/acell(2))
     307                 :           0 :              distz=xcart(3,iatom)-xcart(3,iatom1)
     308                 :           0 :              distz=distz-acell(3)*nint(distz/acell(3))
     309                 :             : !            Here we count each atom below 2 angstr as 1, could be customized
     310                 :           0 :              dist=sqrt(distx*distx+disty*disty+distz*distz)/3.7807
     311                 :           0 :              write(std_out,*) iatom,iatom1,dist
     312         [ #  # ]:           0 :              if (ab_mover%typat(iatom).ne.ab_mover%typat(iatom1)) then
     313                 :             :                mcfac=-1
     314                 :             :              else
     315                 :           0 :                mcfac=1
     316                 :             :              end if
     317         [ #  # ]:           0 :              if (dist<1.0_dp)  dist=1.0_dp
     318                 :             :              pot_perm(iatom)=pot_perm(iatom)+mcfac*(ab_mover%signperm)*1.0_dp&
     319                 :           0 : &             /exp(log(dist)*6.0_dp)
     320                 :             :            end if
     321                 :             :          end do
     322                 :             :        end do
     323                 :           0 :        write(std_out,*) ' Perm_pot ',pot_perm(:)
     324                 :             : !      write(message, '(a,10f12.5)' )' Perm_pot ',&
     325                 :             : !      &         (pot_perm(iatom1),iatom1=1,ab_mover%natom)
     326                 :             : !      call wrtout(ab_out,message,'COLL')
     327                 :             : !      call wrtout(std_out,message,'COLL')
     328                 :             : 
     329                 :             : !      Find the two atoms, of different types, with the highest perm_pot
     330         [ #  # ]:           0 :        max_perm(:)=-1.0d9
     331         [ #  # ]:           0 :        do iatom=1,ab_mover%natom
     332         [ #  # ]:           0 :          if (pot_perm(iatom) > max_perm(ab_mover%typat(iatom))) then
     333                 :           0 :            max_perm(ab_mover%typat(iatom))=pot_perm(iatom)
     334                 :           0 :            imax_perm(ab_mover%typat(iatom))=iatom
     335                 :             :          end if
     336                 :             :        end do
     337                 :             : 
     338         [ #  # ]:           0 :        if(zDEBUG)then
     339                 :             : !        write(message, '(a,10f12.5)' )' max_Perm ',&
     340                 :             : !        &      (max_perm(itypat),itypat=1,ab_mover%ntypat)
     341                 :             : !        call wrtout(std_out,message,'COLL')
     342                 :             : !        write(message, '(a,10i12)' )' imax_Perm ',&
     343                 :             : !        &      (imax_perm(itypat),itypat=1,ab_mover%ntypat)
     344                 :             : !        call wrtout(std_out,message,'COLL')
     345                 :           0 :          write(std_out,*) 'NTYPAT',ab_mover%ntypat
     346                 :           0 :          write(message, '(a,10f12.5)' )' max_Perm ',&
     347         [ #  # ]:           0 : &         (max_perm(:))
     348                 :           0 :          call wrtout(std_out,message,'COLL')
     349                 :           0 :          write(message, '(a,10i12)' )' imax_Perm ',&
     350         [ #  # ]:           0 : &         (imax_perm(:))
     351                 :           0 :          call wrtout(std_out,message,'COLL')
     352                 :             :        end if
     353                 :             : 
     354                 :             : !      Loop and keep the 2 largest values
     355         [ #  # ]:           0 :        if (max_perm(1)>max_perm(2)) then
     356                 :           0 :          maxp1=max_perm(1)
     357                 :           0 :          maxp2=max_perm(2)
     358                 :           0 :          iatom1=imax_perm(1)
     359                 :           0 :          iatom2=imax_perm(2)
     360                 :             :        else
     361                 :           0 :          maxp1=max_perm(2)
     362                 :           0 :          maxp2=max_perm(1)
     363                 :           0 :          iatom1=imax_perm(2)
     364                 :           0 :          iatom2=imax_perm(1)
     365                 :             :        end if
     366                 :             : 
     367         [ #  # ]:           0 :        do itypat=3,ab_mover%ntypat
     368         [ #  # ]:           0 :          if (max_perm(itypat)>maxp1) then
     369                 :           0 :            maxp2=maxp1
     370                 :           0 :            iatom2=iatom1
     371                 :           0 :            maxp1=max_perm(itypat)
     372                 :           0 :            iatom1=imax_perm(itypat)
     373         [ #  # ]:           0 :          else if (max_perm(itypat)>maxp2) then
     374                 :           0 :            maxp2=max_perm(itypat)
     375                 :           0 :            iatom2=imax_perm(itypat)
     376                 :             :          end if
     377                 :             :        end do
     378                 :           0 :        write(message, '(2(a,i5))' )' Will commute atom...',iatom1,'...of type ',&
     379                 :           0 : &       ab_mover%typat(iatom1)
     380                 :           0 :        call wrtout(ab_out,message,'COLL')
     381                 :           0 :        call wrtout(std_out,message,'COLL')
     382                 :           0 :        write(message, '(2(a,i5))' )'         with atom...',iatom2,'...of type ',&
     383                 :           0 : &       ab_mover%typat(iatom2)
     384                 :           0 :        call wrtout(ab_out,message,'COLL')
     385                 :           0 :        call wrtout(std_out,message,'COLL')
     386                 :             : 
     387                 :             : !      Commute the atoms positions
     388                 :           0 :        distx=xcart(1,iatom1)
     389                 :           0 :        disty=xcart(2,iatom1)
     390                 :           0 :        distz=xcart(3,iatom1)
     391                 :           0 :        xcart(1,iatom1)=xcart(1,iatom2)
     392                 :           0 :        xcart(2,iatom1)=xcart(2,iatom2)
     393                 :           0 :        xcart(3,iatom1)=xcart(3,iatom2)
     394                 :           0 :        xcart(1,iatom2)=distx
     395                 :           0 :        xcart(2,iatom2)=disty
     396                 :           0 :        xcart(3,iatom2)=distz
     397                 :             : !      Convert back to xred (reduced coordinates)
     398                 :           0 :        call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
     399                 :             : 
     400                 :             :      end if ! if(mod(itime,ab_mover%delayperm)==0)
     401                 :             : 
     402                 :             :    else
     403                 :             : !    write(std_out,*) "I will jump to the end of cycle"
     404                 :          18 :      jump_end_of_cycle=.TRUE.
     405                 :             : 
     406                 :             :    end if ! if (itime/=1 .and. ab_mover%delayperm/=0 .and. ab_mover%ntypat>2)
     407                 :             : !  End of the commutation section
     408                 :             : 
     409                 :             :  end if ! if (icycle==1)
     410                 :             : 
     411         [ +  - ]:          18 :  ABI_SFREE(imax_perm)
     412                 :             : 
     413                 :             : !write(std_out,*) 'langevin 05',jump_end_of_cycle
     414                 :             : !##########################################################
     415                 :             : !### 05. Compute the next values (Only for extra cycles)
     416                 :             : 
     417         [ -  + ]:          18 :  if (icycle>1) then
     418                 :             : 
     419                 :             : !  write(std_out,*) "Entering internal cycle 2",icycle
     420                 :             : 
     421                 :             : !  If the energy computed is higher than the current
     422                 :             : !  (etotal_temp) we have to discard the changes
     423                 :             : !  and compute again
     424                 :             : 
     425                 :             : !  write(std_out,*) ch10
     426                 :             : !  write(std_out,*) 'EVALUATION FORCES',etotal,hist%etot(abihist_findIndex(hist,-1))
     427                 :             : !  write(std_out,*) ch10
     428                 :             : 
     429                 :             : !  This is the worst case (2 evaluations of SCFCV)
     430                 :           0 :    ihist_prev = abihist_findIndex(hist,-1)
     431   [ #  #  #  # ]:           0 :    if (etotal>hist%etot(ihist_prev).and.icycle==2) then
     432                 :             : 
     433                 :             : !    Discard the changes
     434         [ #  # ]:           0 :      acell(:)   =hist%acell(:,ihist_prev)
     435   [ #  #  #  # ]:           0 :      rprimd(:,:)=hist%rprimd(:,:,ihist_prev)
     436   [ #  #  #  # ]:           0 :      xred(:,:)  =hist%xred(:,:,ihist_prev)
     437   [ #  #  #  # ]:           0 :      fcart(:,:) =hist%fcart(:,:,ihist_prev)
     438         [ #  # ]:           0 :      strten(:)  =hist%strten(:,ihist_prev)
     439   [ #  #  #  # ]:           0 :      vel(:,:)   =hist%vel(:,:,ihist_prev)
     440                 :           0 :      etotal     =hist%etot(ihist_prev)
     441                 :           0 :      call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
     442                 :             : 
     443                 :             : !    distx=xcart(1,iatom1)
     444                 :             : !    disty=xcart(2,iatom1)
     445                 :             : !    distz=xcart(3,iatom1)
     446                 :             : !    xcart(1,iatom1)=xcart(1,iatom2)
     447                 :             : !    xcart(2,iatom1)=xcart(2,iatom2)
     448                 :             : !    xcart(3,iatom1)=xcart(3,iatom2)
     449                 :             : !    xcart(1,iatom2)=distx
     450                 :             : !    xcart(2,iatom2)=disty
     451                 :             : !    xcart(3,iatom2)=distz
     452                 :             : 
     453                 :             : !    Convert back to xred (reduced coordinates)
     454                 :             : !    call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
     455                 :           0 :      write(message, '(a)' )' Commutation unsuccessful, recomputing the forces'
     456                 :           0 :      call wrtout(ab_out,message,'COLL')
     457                 :           0 :      call wrtout(std_out,message,'COLL')
     458                 :             : 
     459                 :             : !    This is the best case (only 1 evaluation of SCFCV)
     460                 :             :    else
     461                 :             : 
     462                 :           0 :      write(message, '(a)')' Commutation successful ! Going on'
     463                 :           0 :      call wrtout(ab_out,message,'COLL')
     464                 :           0 :      call wrtout(std_out,message,'COLL')
     465                 :             : 
     466                 :             : !    In thisc case we do not need to compute again SCFCV
     467                 :             : !    We avoid the second iteration on ii
     468                 :           0 :      jump_end_of_cycle=.TRUE.
     469                 :             : 
     470                 :             :    end if ! etotal > etotal_temp
     471                 :             : 
     472                 :             :  end if ! if (icycle>1)
     473                 :             : 
     474                 :             : !write(std_out,*) 'langevin 06',jump_end_of_cycle
     475                 :             : !##########################################################
     476                 :             : !### 06. Compute the next values (Only for the last cycle)
     477                 :             : 
     478         [ +  - ]:          18 :  if(jump_end_of_cycle)then
     479                 :             : !  icycle=ncycle
     480                 :             : !  write(std_out,*) 'This is the last cycle, avoid the others and continue'
     481                 :          18 :    skipcycle=.TRUE.
     482                 :             :  else
     483                 :           0 :    skipcycle=.FALSE.
     484                 :             :  end if
     485                 :             : 
     486   [ +  +  +  - ]:          18 :  if ((icycle==ncycle).OR.(skipcycle)) then
     487                 :             : 
     488                 :             : !  write(std_out,*) 'ENTERING THE FINAL PART',icycle,ncycle
     489                 :             : 
     490                 :             : !  Specific to Langevin dynamics
     491                 :             : !  Initialize an array of random forces
     492                 :             : !  No random force at itime=0
     493                 :             : !  if (itime==0) then
     494         [ -  + ]:          18 :    if (itime<0) then
     495                 :             : 
     496   [ #  #  #  # ]:           0 :      ran_force(:,:)=0.0_dp
     497                 :             : 
     498                 :             :    else
     499                 :             : 
     500         [ +  + ]:          63 :      do iatom=1,ab_mover%natom
     501                 :             : !      sig_gauss is the std deviation of the random distribution
     502                 :          45 :        sig_gauss=sqrt(2.0_dp*(ab_mover%friction)*ab_mover%amass(iatom)*ktemp)
     503                 :             : !      write(std_out,*) 'sig_gauss=',sig_gauss
     504                 :             : !      write(std_out,*) 'friction=',ab_mover%friction
     505                 :             : !      write(std_out,*) 'ktemp=',ktemp
     506         [ +  + ]:         198 :        do idim=1,3
     507                 :         135 :          delxi=2.0_dp
     508         [ +  + ]:         306 :          do while (delxi >= 1.0_dp)
     509                 :         171 :            ran_num1=2.0_dp*uniformrandom(idum)-1.0_dp
     510                 :         171 :            ran_num2=2.0_dp*uniformrandom(idum)-1.0_dp
     511                 :         171 :            delxi=ran_num1*ran_num1+ran_num2*ran_num2
     512                 :             : !          write(std_out,*) delxi,ran_num1,ran_num2
     513                 :             :          end do
     514                 :             :          ran_force(idim,iatom)=ran_num1*sqrt(-2.0_dp*log(delxi)/delxi)&
     515                 :         180 : &         *sig_gauss/sqrt(ab_mover%dtion)
     516                 :             : !        write(std_out,*) 'ran_force',ran_force(idim,iatom)
     517                 :             :        end do
     518                 :             :      end do
     519                 :             : 
     520         [ -  + ]:          18 :      if (zDEBUG) then
     521                 :           0 :        write (std_out,*) '4. Different forces computed'
     522                 :           0 :        write (std_out,*) 'RAN_FORCE'
     523         [ #  # ]:           0 :        do kk=1,ab_mover%natom
     524                 :           0 :          write (std_out,*) ran_force(:,kk)
     525                 :             :        end do
     526                 :             :      end if
     527                 :             : 
     528                 :             : 
     529         [ -  + ]:          18 :      if(zDEBUG)then
     530                 :             : !      The distribution should be gaussian
     531                 :           0 :        delxi=0.0_dp
     532         [ #  # ]:           0 :        do iatom=1,ab_mover%natom
     533         [ #  # ]:           0 :          do idim=1,3
     534                 :           0 :            delxi=delxi+(ran_force(idim,iatom)*ab_mover%dtion)**2
     535                 :             :          end do
     536                 :             :        end do
     537                 :           0 :        delxi=delxi/(3.0_dp*ab_mover%natom)
     538                 :           0 :        write(message, '(2(a,es22.14))' )' variance =',delxi,'  asked =',&
     539                 :           0 : &       2.0_dp*(ab_mover%friction)*ab_mover%amass(2)*ktemp*ab_mover%dtion
     540                 :           0 :        call wrtout(std_out,message,'COLL')
     541                 :             :      end if
     542                 :             : !    end if itime\=0
     543                 :             : 
     544                 :             :    end if
     545                 :             : 
     546                 :             : !  zDEBUG
     547                 :             : !  write(message, '(a)' )' after initializing ran_force'
     548                 :             : !  call wrtout(ab_out,message,'COLL')
     549                 :             : !  call wrtout(std_out,message,'COLL')
     550                 :             : !  ENDzDEBUG
     551                 :             : 
     552         [ +  + ]:          63 :    do iatom=1,ab_mover%natom
     553         [ +  + ]:         198 :      do idim=1,3
     554                 :         135 :        fcart_m(idim,iatom)=fcart(idim,iatom)/ab_mover%amass(iatom)
     555                 :         180 :        ran_force(idim,iatom)=ran_force(idim,iatom)/ab_mover%amass(iatom)
     556                 :             :      end do
     557                 :             :    end do
     558   [ +  +  +  + ]:         198 :    lang_force(:,:)=ran_force(:,:)-(ab_mover%friction)*vel(:,:)+fcart_m(:,:)
     559                 :             : 
     560         [ -  + ]:          18 :    if (zDEBUG) then
     561                 :           0 :      write (std_out,*) '4. Different forces computed'
     562                 :           0 :      write (std_out,*) 'FCART_M'
     563         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     564                 :           0 :        write (std_out,*) fcart_m(:,kk)
     565                 :             :      end do
     566                 :           0 :      write (std_out,*) 'RAN_FORCE'
     567         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     568                 :           0 :        write (std_out,*) ran_force(:,kk)
     569                 :             :      end do
     570                 :           0 :      write (std_out,*) 'LANG_FORCE'
     571         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     572                 :           0 :        write (std_out,*) lang_force(:,kk)
     573                 :             :      end do
     574                 :             :    end if
     575                 :             : 
     576                 :             : !  zDEBUG
     577                 :             : !  write(message, '(a)' )'before verlet'
     578                 :             : !  call wrtout(ab_out,message,'COLL')
     579                 :             : !  call wrtout(std_out,message,'COLL')
     580                 :             : !  ENDzDEBUG
     581                 :             : 
     582                 :             : !  Compute next atomic coordinates using Verlet algorithm
     583                 :             : 
     584                 :             : !  Impose no change of acell, ucvol, rprim, and rprimd
     585                 :          18 :    acell_next(:)=acell(:)
     586                 :          18 :    ucvol_next=ucvol
     587                 :          18 :    rprim_next(:,:)=rprim(:,:)
     588                 :          18 :    rprimd_next(:,:)=rprimd(:,:)
     589                 :             : 
     590                 :             : !  Convert input xred (reduced coordinates) to xcart (cartesian)
     591                 :          18 :    call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
     592                 :             : !  Uses the velocity
     593                 :             : !
     594                 :             : !  If an atom wants to cross the walls, velocity is reversed.
     595                 :             : !
     596         [ +  + ]:          63 :    do iatom=1,ab_mover%natom
     597         [ +  + ]:         198 :      do idim=1,3
     598                 :             :        delxi=xcart(idim,iatom)+ab_mover%dtion*vel(idim,iatom)+ &
     599                 :         135 : &       0.5_dp*ab_mover%dtion*ab_mover%dtion*lang_force(idim,iatom)
     600   [ +  -  -  + ]:         135 :        if ( (delxi > (rprimd(idim,idim)+(ab_mover%mdwall)) ) .or. &
     601                 :             : &       (delxi < - (ab_mover%mdwall)                   )       ) then
     602                 :           0 :          vel(idim,iatom)=-vel(idim,iatom)
     603                 :             :          delxi=xcart(idim,iatom)+ab_mover%dtion*vel(idim,iatom)+ &
     604                 :           0 : &         0.5_dp*ab_mover%dtion*ab_mover%dtion*lang_force(idim,iatom)
     605                 :             :        end if
     606                 :         180 :        xcart_next(idim,iatom)=delxi
     607                 :             :      end do
     608                 :             :    end do
     609   [ +  +  +  + ]:         198 :    xcart(:,:)=xcart_next(:,:)
     610         [ -  + ]:          18 :    if (zDEBUG) then
     611                 :           0 :      write (std_out,*) '5. If an atom wants to cross the walls, velocity is reversed.'
     612                 :           0 :      write (std_out,*) 'XCART'
     613         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     614                 :           0 :        write (std_out,*) xcart(:,kk)
     615                 :             :      end do
     616                 :             :    end if
     617                 :             : 
     618                 :             : !  Convert back to xred_next (reduced coordinates)
     619                 :          18 :    call xcart2xred(ab_mover%natom,rprimd,xcart_next,xred_next)
     620                 :          18 :    call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
     621                 :             : 
     622         [ +  + ]:          18 :    if (itime==1) then
     623                 :             : !    no old forces are available at first step
     624                 :             : !    Simple update of the velocity
     625                 :             : !    first compute vel_nexthalf for next steps
     626   [ +  +  +  + ]:          22 :      vel(:,:)=vel(:,:)+ab_mover%dtion*lang_force(:,:)
     627                 :             :    else
     628                 :             : !    case itime /= 0 normal verlet integration
     629   [ +  +  +  + ]:         176 :      vel(:,:)=vel(:,:)+0.5_dp*ab_mover%dtion*(fcart_mold(:,:)+lang_force(:,:))
     630                 :             :    end if
     631         [ -  + ]:          18 :    if (zDEBUG) then
     632                 :           0 :      write (std_out,*) '5. Change velocity with verlet'
     633                 :           0 :      write (std_out,*) 'VEL'
     634         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     635                 :           0 :        write (std_out,*) vel(:,kk)
     636                 :             :      end do
     637                 :             :    end if
     638                 :             : 
     639                 :             : !  Store 'current force' as 'old force'
     640   [ +  +  +  + ]:         198 :    fcart_mold(:,:)=lang_force(:,:)
     641                 :             : 
     642                 :             :  end if ! if (icycle==ncycle)
     643                 :             : 
     644                 :             : !write(std_out,*) 'langevin 07',jump_end_of_cycle
     645                 :             : !##########################################################
     646                 :             : !### 07. Update the history with the prediction
     647                 :             : 
     648                 :             : !Increase indexes
     649                 :          18 :  hist%ihist = abihist_findIndex(hist,+1)
     650                 :             : 
     651                 :          18 :  call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     652   [ +  +  +  + ]:         198 :  hist%vel(:,:,hist%ihist)=vel(:,:)
     653                 :          18 :  hist%time(hist%ihist)=real(itime,kind=dp)*ab_mover%dtion
     654                 :             : 
     655   [ +  -  +  - ]:          18 :  if (ab_mover%delayperm==0 .or. ab_mover%ntypat<=2) ncycle=1
     656         [ +  + ]:          18 :  if(itime==ntime-1) ncycle=1
     657                 :             : 
     658                 :             : end subroutine pred_langevin
     659                 :             : !!***
     660                 :             : 
     661                 :             : end module m_pred_langevin
     662                 :             : !!***
        

Generated by: LCOV version 2.3-1