LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_pred_verlet.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 68.8 % 199 137
Test Date: 2026-11-09 13:21:34 Functions: 100.0 % 1 1
Branches: 55.0 % 360 198

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_pred_verlet
       2                 :             : !! NAME
       3                 :             : !!  m_pred_verlet
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, JCC, SE)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_pred_verlet
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_abimover
      27                 :             :  use m_abihist
      28                 :             :  use m_xfpack
      29                 :             : 
      30                 :             :  use m_geometry,       only : mkrdim, xcart2xred, xred2xcart, fcart2gred, metric
      31                 :             : 
      32                 :             :  implicit none
      33                 :             : 
      34                 :             :  private
      35                 :             : !!***
      36                 :             : 
      37                 :             :  public :: pred_verlet
      38                 :             : !!***
      39                 :             : 
      40                 :             : contains
      41                 :             : !!***
      42                 :             : 
      43                 :             : !!****f* ABINIT/pred_verlet
      44                 :             : !! NAME
      45                 :             : !! pred_verlet
      46                 :             : !!
      47                 :             : !! FUNCTION
      48                 :             : !! Ionmov predictors (6 & 7) Verlet algorithm
      49                 :             : !!
      50                 :             : !! IONMOV 6:
      51                 :             : !! Given a starting point xred that is a vector of length 3*natom
      52                 :             : !! (reduced nuclei coordinates), a velocity vector (in cartesian
      53                 :             : !! coordinates), and unit cell parameters (acell and rprimd -
      54                 :             : !! without velocities in the present implementation), the Verlet
      55                 :             : !! dynamics is performed, using the gradient of the energy
      56                 :             : !! (atomic forces and stresses) as calculated by the routine scfcv.
      57                 :             : !!
      58                 :             : !! Some atoms can be kept fixed, while the propagation of unit cell
      59                 :             : !! parameters is only performed if optcell/=0.
      60                 :             : !! No more than ab_mover%ntime steps are performed.
      61                 :             : !! The time step is governed by dtion, contained in ab_mover
      62                 :             : !! (coming from dtset).
      63                 :             : !! Returned quantities are xred, and eventually acell and rprimd (new ones!).
      64                 :             : !!
      65                 :             : !! IONMOV 7:
      66                 :             : !! Block every atom for which the scalar product of velocity and
      67                 :             : !! forces is negative, in order to reach the minimum.
      68                 :             : !! The convergence requirement on the atomic forces, ab_mover%tolmxf,
      69                 :             : !! allows an early exit.
      70                 :             : !!
      71                 :             : !! INPUTS
      72                 :             : !! ab_mover <type(abimover)> : Datatype with all the information needed by the preditor
      73                 :             : !! itime  : Index of the present iteration
      74                 :             : !! ntime  : Maximal number of iterations
      75                 :             : !! ionmov : (6 or 7) Specific kind of VERLET
      76                 :             : !! zDEBUG : if true print some debugging information
      77                 :             : !!
      78                 :             : !! SIDE EFFECTS
      79                 :             : !! hist <type(abihist)> : History of positions,forces
      80                 :             : !!                               acell, rprimd, stresses
      81                 :             : !!
      82                 :             : !! SOURCE
      83                 :             : 
      84                 :          53 : subroutine pred_verlet(ab_mover,hist,ionmov,itime,ntime,zDEBUG,iexit)
      85                 :             : 
      86                 :             :  implicit none
      87                 :             : 
      88                 :             : !Arguments ------------------------------------
      89                 :             : !scalars
      90                 :             :  type(abimover),intent(in) :: ab_mover
      91                 :             :  type(abihist),intent(inout) :: hist
      92                 :             :  integer,intent(in) :: itime
      93                 :             :  integer,intent(in) :: ntime
      94                 :             :  integer,intent(in) :: ionmov
      95                 :             :  integer,intent(in) :: iexit
      96                 :             :  logical,intent(in) :: zDEBUG
      97                 :             : 
      98                 :             : !Local variables-------------------------------
      99                 :             : !scalars
     100                 :             :  integer  :: ii,istopped,jj,kk,ndim,nstopped
     101                 :             :  real(dp) :: amass_tot,etotal,diag,gr_avg,ekin_corr,scprod,taylor,ucvol0
     102                 :             :  real(dp),save :: ucvol,ucvol_next
     103                 :             :  character(len=500) :: message
     104                 :             : !arrays
     105                 :         106 :  integer  :: stopped(ab_mover%natom)
     106                 :         106 :  real(dp) :: acell0(3),fcart(3,ab_mover%natom)
     107                 :         106 :  real(dp) :: gred_corrected(3,ab_mover%natom)
     108                 :             :  real(dp) :: gprimd(3,3),gmet(3,3),rmet(3,3), strten(6)
     109                 :         106 :  real(dp) :: xcart(3,ab_mover%natom),xcart_next(3,ab_mover%natom)
     110                 :         106 :  real(dp) :: xred(3,ab_mover%natom),xred_next(3,ab_mover%natom)
     111                 :          53 :  real(dp) :: vel(3,ab_mover%natom),vel_nexthalf(3,ab_mover%natom)
     112                 :             :  real(dp),save :: acell(3),acell_next(3)
     113                 :             :  real(dp),save :: rprimd(3,3),rprim(3,3),rprimd_next(3,3),rprim_next(3,3)
     114                 :             :  real(dp),allocatable,save :: hessin(:,:)
     115                 :             :  real(dp),allocatable,save :: vin(:),vin_prev(:),vin_next(:)
     116                 :             :  real(dp),allocatable,save :: vout(:),vout_prev(:),vel_prevhalf(:,:)
     117                 :             : 
     118                 :             : !***************************************************************************
     119                 :             : !Beginning of executable session
     120                 :             : !***************************************************************************
     121                 :             : 
     122         [ +  + ]:          53 :  if(iexit/=0)then
     123         [ +  - ]:           5 :     ABI_SFREE(vin)
     124         [ +  - ]:           5 :     ABI_SFREE(vin_next)
     125         [ +  - ]:           5 :     ABI_SFREE(vout)
     126         [ +  - ]:           5 :     ABI_SFREE(vin_prev)
     127         [ +  - ]:           5 :     ABI_SFREE(vout_prev)
     128         [ +  - ]:           5 :     ABI_SFREE(hessin)
     129         [ +  - ]:           5 :     ABI_SFREE(vel_prevhalf)
     130                 :             :    return
     131                 :             :  end if
     132                 :             : 
     133                 :             : !write(std_out,*) 'verlet 01'
     134                 :             : !##########################################################
     135                 :             : !### 01. Compute the dimension of vectors (ndim)
     136                 :             : 
     137                 :          48 :  ndim=3*ab_mover%natom
     138         [ -  + ]:          48 :  if(ab_mover%optcell==1) ndim=ndim+1
     139         [ -  + ]:          48 :  if(ab_mover%optcell==2 .or.&
     140                 :           0 : & ab_mover%optcell==3) ndim=ndim+6
     141         [ -  + ]:          48 :  if(ab_mover%optcell>=4) ndim=ndim+3
     142                 :             : 
     143                 :             : !write(std_out,*) 'verlet 02'
     144                 :             : !##########################################################
     145                 :             : !### 02. Allocate the vectors vin, vout and hessian matrix
     146                 :             : 
     147                 :             : !Notice that vin, vout, etc could be allocated
     148                 :             : !From a previous dataset with a different ndim
     149         [ +  + ]:          48 :  if(itime==1)then
     150         [ -  + ]:           5 :    ABI_SFREE(vin)
     151         [ -  + ]:           5 :    ABI_SFREE(vin_next)
     152         [ -  + ]:           5 :    ABI_SFREE(vout)
     153         [ -  + ]:           5 :    ABI_SFREE(vin_prev)
     154         [ -  + ]:           5 :    ABI_SFREE(vout_prev)
     155         [ -  + ]:           5 :    ABI_SFREE(hessin)
     156         [ -  + ]:           5 :    ABI_SFREE(vel_prevhalf)
     157                 :             : 
     158   [ -  +  +  -  :          15 :    ABI_MALLOC(vin,(ndim))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     159   [ -  +  +  -  :          10 :    ABI_MALLOC(vin_next,(ndim))
          -  +  -  +  -  
                      + ]
     160   [ -  +  +  -  :          10 :    ABI_MALLOC(vout,(ndim))
          -  +  -  +  -  
                      + ]
     161   [ -  +  +  -  :          10 :    ABI_MALLOC(vin_prev,(ndim))
          -  +  -  +  -  
                      + ]
     162   [ -  +  +  -  :          10 :    ABI_MALLOC(vout_prev,(ndim))
          -  +  -  +  -  
                      + ]
     163   [ -  +  +  -  :          20 :    ABI_MALLOC(hessin,(ndim,ndim))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     164   [ -  +  +  -  :          15 :    ABI_MALLOC(vel_prevhalf,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     165                 :             :  end if
     166                 :             : 
     167                 :             : !write(std_out,*) 'verlet 03'
     168                 :             : !##########################################################
     169                 :             : !### 03. Obtain the present values from the history
     170                 :             : 
     171                 :          48 :  call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     172                 :             : 
     173                 :          48 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     174         [ +  + ]:         192 :  do ii=1,3
     175         [ +  + ]:         624 :    rprim(ii,1:3)=rprimd(ii,1:3)/acell(1:3)
     176                 :             :  end do
     177                 :             : 
     178                 :          48 :  call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
     179   [ +  +  +  + ]:         432 :  fcart(:,:)  =hist%fcart(:,:,hist%ihist)
     180         [ +  + ]:         336 :  strten(:)  =hist%strten(:,hist%ihist)
     181   [ +  +  +  + ]:         432 :  vel(:,:)   =hist%vel(:,:,hist%ihist)
     182                 :          48 :  etotal     =hist%etot(hist%ihist)
     183                 :             : 
     184         [ -  + ]:          48 :  if(zDEBUG)then
     185                 :           0 :    write (std_out,*) 'fcart:'
     186         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     187                 :           0 :      write (std_out,*) fcart(:,kk)
     188                 :             :    end do
     189                 :           0 :    write (std_out,*) 'vel:'
     190         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     191                 :           0 :      write (std_out,*) vel(:,kk)
     192                 :             :    end do
     193                 :           0 :    write (std_out,*) 'strten:'
     194                 :           0 :    write (std_out,*) strten(1:3),ch10,strten(4:6)
     195                 :           0 :    write (std_out,*) 'etotal:'
     196                 :           0 :    write (std_out,*) etotal
     197                 :             :  end if
     198                 :             : 
     199                 :          48 :  acell0=acell ; ucvol0=ucvol
     200                 :             : 
     201                 :             : !Get rid of mean force on whole unit cell, but only if no
     202                 :             : !generalized constraints are in effect
     203                 :          48 :  call fcart2gred(fcart,gred_corrected,rprimd,ab_mover%natom)
     204         [ +  - ]:          48 :  if(ab_mover%nconeq==0)then
     205         [ +  + ]:         144 :    amass_tot=sum(ab_mover%amass(:))
     206         [ +  + ]:         192 :    do kk=1,3
     207   [ +  +  +  - ]:         192 :      if (kk/=3.or.ab_mover%jellslab==0) then
     208         [ +  + ]:         432 :        gr_avg=sum(gred_corrected(kk,:))/dble(ab_mover%natom)
     209         [ +  + ]:         432 :        gred_corrected(kk,:)=gred_corrected(kk,:)-gr_avg*ab_mover%amass(:)/amass_tot
     210                 :             :      end if
     211                 :             :    end do
     212                 :             :  end if
     213                 :             : 
     214                 :             : !write(std_out,*) 'verlet 04'
     215                 :             : !##########################################################
     216                 :             : !### 04. Fill the vectors vin and vout
     217                 :             : 
     218                 :             : !Initialize input vectors : first vin, then vout
     219                 :             :  call xfpack_x2vin(acell, ab_mover%natom, ndim,&
     220                 :             : & ab_mover%nsym, ab_mover%optcell, rprim, rprimd,&
     221   [ +  -  -  -  :          48 : & ab_mover%symrel, ucvol, ucvol0, vin, xred)
          -  -  -  -  -  
                -  -  + ]
     222                 :             :  call xfpack_f2vout(gred_corrected, ab_mover%natom, ndim,&
     223                 :             : & ab_mover%optcell, ab_mover%strtarget, strten, ucvol,&
     224   [ +  -  -  -  :          48 : & vout)
             -  -  -  + ]
     225                 :             : 
     226                 :             : !write(std_out,*) 'verlet 05'
     227                 :             : !##########################################################
     228                 :             : !### 05. Initialize or update the hessian matrix
     229                 :             : 
     230                 :             : !Here, set up the matrix of transformation between forces and
     231                 :             : !acceleration. Masses must be included here.
     232                 :             : !Beside this feature, one could define
     233                 :             : !a preconditioner, in which case it should
     234                 :             : !be the inverse hessian, like in Broyden. This explains the
     235                 :             : !name chosen for this transformation matrix. This would allow
     236                 :             : !to find easily the optimal geometry with ionmov=7.
     237                 :             : !The default, now implemented, corresponds to the identity matrix
     238                 :             : !in cartesian coordinates, which makes use of metric tensor gmet
     239                 :             : !in reduced coordinates.
     240                 :             : 
     241                 :             : !Initialise the Hessian matrix using gmet
     242         [ +  + ]:          48 :  if (itime==1)then
     243                 :             : !  Initialize inverse hessian with identity matrix
     244                 :             : !  in cartesian coordinates, which makes use of metric tensor gmet
     245                 :             : !  in reduced coordinates.
     246   [ +  +  +  + ]:         215 :    hessin(:,:)=zero
     247         [ +  + ]:          15 :    do ii=1,ab_mover%natom
     248         [ +  + ]:          45 :      do kk=1,3
     249         [ +  + ]:         130 :        do jj=1,3
     250                 :             : !        Warning : implemented in reduced coordinates
     251   [ +  -  +  - ]:          90 :          if (ab_mover%iatfix(kk,ii)==0 .and.&
     252                 :          30 : &         ab_mover%iatfix(jj,ii)==0 )then
     253                 :          90 :            hessin(kk+3*(ii-1),jj+3*(ii-1))=gmet(kk,jj)/ab_mover%amass(ii)
     254                 :             :          end if
     255                 :             :        end do
     256                 :             :      end do
     257                 :             :    end do
     258         [ -  + ]:           5 :    if(ab_mover%optcell/=0)then
     259                 :             : !    These values might lead to too large changes in some cases ...
     260                 :           0 :      diag=ab_mover%strprecon*30.0_dp/ucvol
     261         [ #  # ]:           0 :      if(ab_mover%optcell==1) diag=diag/three
     262         [ #  # ]:           0 :      do ii=3*ab_mover%natom+1,ndim
     263                 :           0 :        hessin(ii,ii)=diag
     264                 :             :      end do
     265                 :             :    end if
     266                 :             :  end if
     267                 :             : 
     268                 :             : !zDEBUG (vin,vout and hessin before prediction)
     269         [ -  + ]:          48 :  if(zDEBUG)then
     270                 :           0 :    write(std_out,*) 'Vectors vin and vout and inverse of Hessian (hessin) [before]'
     271                 :           0 :    write(std_out,*) 'vin:'
     272   [ #  #  #  # ]:           0 :    do ii=1,ndim,3
     273         [ #  # ]:           0 :      if (ii+2<=ndim)then
     274                 :           0 :        write(std_out,*) ii,vin(ii:ii+2)
     275                 :             :      else
     276                 :           0 :        write(std_out,*) ii,vin(ii:ndim)
     277                 :             :      end if
     278                 :             :    end do
     279                 :           0 :    write(std_out,*) 'vout:'
     280   [ #  #  #  # ]:           0 :    do ii=1,ndim,3
     281         [ #  # ]:           0 :      if (ii+2<=ndim)then
     282                 :           0 :        write(std_out,*) ii,vout(ii:ii+2)
     283                 :             :      else
     284                 :           0 :        write(std_out,*) ii,vout(ii:ndim)
     285                 :             :      end if
     286                 :             :    end do
     287                 :           0 :    write(std_out,*) 'Inverse Hessian (hessin): ',ndim,'x',ndim
     288         [ #  # ]:           0 :    do kk=1,ndim
     289   [ #  #  #  # ]:           0 :      do jj=1,ndim,3
     290         [ #  # ]:           0 :        if (jj+2<=ndim)then
     291                 :           0 :          write(std_out,*) jj,hessin(jj:jj+2,kk)
     292                 :             :        else
     293                 :           0 :          write(std_out,*) jj,hessin(jj:ndim,kk)
     294                 :             :        end if
     295                 :             :      end do
     296                 :             :    end do
     297                 :             :  end if
     298                 :             : 
     299                 :             : !write(std_out,*) 'verlet 06'
     300                 :             : !##########################################################
     301                 :             : !### 06. Compute the next values
     302                 :             : 
     303                 :             : !%%% VERLET ALGORITHM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     304                 :             : 
     305         [ -  + ]:          48 :  if(zDEBUG)then
     306                 :           0 :    write(std_out,*) 'Shifted data ENTER'
     307                 :           0 :    write(std_out,*) 'acell(:)',acell(:)
     308                 :           0 :    write(std_out,*) 'rprimd(:,:)',rprimd(:,:)
     309                 :           0 :    write(std_out,*) 'ucvol',ucvol
     310                 :           0 :    write(std_out,*) 'vel_prevhalf(:,:)',vel_prevhalf(:,:)
     311                 :           0 :    write(std_out,*) 'vin_prev(:)',vin_prev(:)
     312                 :           0 :    write(std_out,*) 'vin(:)',vin(:)
     313                 :           0 :    write(std_out,*) 'xcart(:,:)',xcart(:,:)
     314                 :           0 :    write(std_out,*) 'xred(:,:)',xred(:,:)
     315                 :             :  end if
     316                 :             : 
     317                 :             : !Compute next atomic coordinates and cell parameters, using
     318                 :             : !Verlet algorithm
     319                 :             : 
     320                 :             : !1. First propagate the position, without acceleration
     321         [ +  + ]:          48 :  if(itime/=1)then
     322         [ +  + ]:         301 :    vin_next(:)=2*vin(:)-vin_prev(:)
     323                 :             :    taylor=one
     324                 :             :  else
     325                 :             : !  Initialisation : no vin_prev is available, but the ionic velocity
     326                 :             : !  is available, in cartesian coordinates
     327                 :             : !  Uses the velocity
     328   [ +  +  +  + ]:          45 :    xcart_next(:,:)=xcart(:,:)+ab_mover%dtion*vel(:,:)
     329                 :             : !  Convert back to xred_next (reduced coordinates)
     330                 :           5 :    call xcart2xred(ab_mover%natom,rprimd,xcart_next,xred_next)
     331                 :             : !  Impose no change of acell, ucvol, rprim, and rprimd
     332                 :           5 :    acell_next(:)=acell(:)
     333                 :           5 :    ucvol_next=ucvol
     334                 :           5 :    rprim_next(:,:)=rprim(:,:)
     335                 :           5 :    rprimd_next(:,:)=rprimd(:,:)
     336                 :           5 :    write(std_out,*) 'ucvol',ucvol
     337                 :             : !  Store all these next values in vin_next
     338                 :             :    call xfpack_x2vin(acell_next,ab_mover%natom,&
     339                 :             : &   ndim,ab_mover%nsym,ab_mover%optcell,rprim_next,&
     340                 :             : &   rprimd,ab_mover%symrel,ucvol_next,ucvol0,&
     341   [ +  -  -  -  :           5 : &   vin_next,xred_next)
          -  -  -  -  -  
                -  -  + ]
     342                 :           5 :    taylor=half
     343                 :             :  end if
     344                 :             : 
     345                 :             : !2. Now, take into account the acceleration
     346         [ +  + ]:         336 :  do ii=1,ndim
     347                 :             : !  Note the minus sign: the forces are minus the gradients,
     348                 :             : !  contained in vout.
     349                 :             :    vin_next(:)=vin_next(:)-ab_mover%dtion**2*hessin(:,ii)*&
     350         [ +  + ]:        2064 : &   vout(ii)*taylor
     351                 :             :  end do
     352                 :             : 
     353                 :             : !3. Implement fixing of atoms : put back old values for fixed
     354                 :             : !components
     355         [ +  + ]:         144 :  do kk=1,ab_mover%natom
     356         [ +  + ]:         432 :    do jj=1,3
     357                 :             : !    Warning : implemented in reduced coordinates
     358         [ -  + ]:         384 :      if (ab_mover%iatfix(jj,kk) == 1) then
     359                 :           0 :        vin_next(jj+(kk-1)*3)=vin(jj+(kk-1)*3)
     360                 :             :      end if
     361                 :             :    end do
     362                 :             :  end do
     363                 :             : 
     364                 :             : !4. Now, compute the velocity at the next half-step
     365                 :             : !Get xred_next, and eventually acell_next, ucvol_next, rprim_next and
     366                 :             : !rprimd_next, from vin_next
     367                 :             :  call xfpack_vin2x(acell_next,acell0,ab_mover%natom,ndim,&
     368                 :             : & ab_mover%nsym,ab_mover%optcell,rprim_next,rprimd,&
     369   [ +  -  -  -  :          48 : & ab_mover%symrel,ucvol_next,ucvol0,vin_next,xred_next)
          -  -  -  -  -  
                -  -  + ]
     370         [ -  + ]:          48 :  if(ab_mover%optcell/=0)then
     371                 :           0 :    call mkrdim(acell_next,rprim_next,rprimd_next)
     372                 :           0 :    call metric(gmet,gprimd,-1,rmet,rprimd_next,ucvol_next)
     373                 :             :  else
     374                 :          48 :    rprimd_next(:,:)=rprimd(:,:)
     375                 :             :  end if
     376                 :             : !Convert input xred_next (reduced coordinates) to
     377                 :             : !xcart_next (cartesian)
     378                 :          48 :  call xred2xcart(ab_mover%natom,rprimd_next,xcart_next,xred_next)
     379                 :             : !Compute the velocity at half of the new step
     380   [ +  +  +  + ]:         432 :  vel_nexthalf(:,:)=(xcart_next(:,:)-xcart(:,:))/ab_mover%dtion
     381                 :             : 
     382                 :             : !5. If needed, compute the velocity at present position
     383         [ +  + ]:          48 :  if(itime/=1)then
     384   [ +  +  +  + ]:         387 :    vel(:,:)=(vel_nexthalf(:,:)+vel_prevhalf(:,:))*0.5_dp
     385                 :             :  end if
     386                 :             : 
     387                 :             : !%%% VERLET ALGORITHM BLOCKING ATOMS %%%%%%%%%%%%%%%%%%%%%%
     388                 :             : 
     389                 :             : !Here, stop the atoms for which the scalar product of velocity
     390                 :             : !and force is negative, and recompute the kinetic energy.
     391         [ +  + ]:          48 :  if(ionmov==7)then
     392         [ +  + ]:          87 :    stopped(:)=0
     393         [ +  + ]:          87 :    do ii=1,ab_mover%natom
     394                 :             :      scprod=fcart(1,ii)*vel(1,ii)+&
     395                 :             : &     fcart(2,ii)*vel(2,ii)+&
     396                 :          58 : &     fcart(3,ii)*vel(3,ii)
     397   [ +  +  +  - ]:          87 :      if(scprod<0.0_dp .and. itime/=1)then
     398                 :          26 :        stopped(ii)=1
     399                 :          26 :        write(std_out,*) 'Stopped atom',ii
     400                 :             : !      Shift the velocities of the previous half-step and current
     401                 :             : !      half-step, so that the acceleration is correct but the
     402                 :             : !      present velocity vanishes.
     403         [ +  + ]:         104 :        vel_prevhalf(:,ii)=vel_prevhalf(:,ii)-vel(:,ii)
     404         [ +  + ]:         104 :        vel_nexthalf(:,ii)=vel_nexthalf(:,ii)-vel(:,ii)
     405         [ +  + ]:         104 :        vel(:,ii)=0.0_dp
     406         [ +  + ]:         104 :        xcart_next(:,ii)=xcart(:,ii)+ab_mover%dtion*vel_nexthalf(:,ii)
     407                 :             :      end if
     408                 :             :    end do
     409                 :             : 
     410         [ -  + ]:          29 :    if(zDEBUG)then
     411                 :           0 :      write (std_out,*) 'fcart:'
     412         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     413                 :           0 :        write (std_out,*) fcart(:,kk)
     414                 :             :      end do
     415                 :           0 :      write (std_out,*) 'vel_prevhalf:'
     416         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     417                 :           0 :        write (std_out,*) vel_prevhalf(:,kk)
     418                 :             :      end do
     419                 :           0 :      write (std_out,*) 'vel_nexthalf:'
     420         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     421                 :           0 :        write (std_out,*) vel_nexthalf(:,kk)
     422                 :             :      end do
     423                 :           0 :      write (std_out,*) 'vel:'
     424         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     425                 :           0 :        write (std_out,*) vel(:,kk)
     426                 :             :      end do
     427                 :           0 :      write (std_out,*) 'xcart_next:'
     428         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     429                 :           0 :        write (std_out,*) xcart_next(:,kk)
     430                 :             :      end do
     431                 :             :    end if
     432                 :             : 
     433                 :             : !  Establish a list of stopped atoms
     434         [ +  + ]:          87 :    nstopped=sum(stopped(:))
     435                 :             : 
     436         [ +  + ]:          29 :    if(nstopped/=0)then
     437                 :          13 :      write(message,'(a)') ' List of stopped atoms (ionmov=7) :'
     438                 :          13 :      call wrtout(ab_out,message,'COLL')
     439                 :          13 :      istopped=1
     440         [ +  + ]:          39 :      do ii=1,ab_mover%natom
     441         [ +  - ]:          39 :        if(stopped(ii)==1)then
     442                 :          26 :          stopped(istopped)=ii
     443                 :          26 :          istopped=istopped+1
     444                 :             :        end if
     445                 :             :      end do
     446   [ -  +  -  + ]:          26 :      do ii=1,nstopped,16
     447                 :          13 :        write(message, '(16i4)' ) stopped(ii:min(ii+15,nstopped))
     448                 :          26 :        call wrtout(ab_out,message,'COLL')
     449                 :             :      end do
     450                 :             : !    Now, compute the corrected kinetic energy
     451                 :             : !    Generate xred_next from xcart_next
     452                 :          13 :      call xcart2xred(ab_mover%natom,rprimd_next,xcart_next,xred_next)
     453                 :             : !    Store xred_next, and eventual acell_next and rprim_next in vin
     454                 :             :      call xfpack_x2vin(acell_next,&
     455                 :             : &     ab_mover%natom,ndim,ab_mover%nsym,ab_mover%optcell,&
     456                 :             : &     rprim_next,rprimd,&
     457   [ +  -  -  -  :          13 : &     ab_mover%symrel,ucvol_next,ucvol0,vin_next,xred_next)
          -  -  -  -  -  
                -  -  + ]
     458                 :             : 
     459                 :          13 :      ekin_corr=0.0_dp
     460         [ +  + ]:          39 :      do ii=1,ab_mover%natom
     461         [ +  + ]:         117 :        do jj=1,3
     462                 :             : !        Warning : the fixing of atomis is implemented in reduced
     463                 :             : !        coordinates, so that this expression is wrong
     464                 :         104 :          if (ab_mover%iatfix(jj,ii) == 0) then
     465                 :             :            ekin_corr=ekin_corr+0.5_dp*ab_mover%amass(ii)*vel(jj,ii)**2
     466                 :             :          end if
     467                 :             :        end do
     468                 :             :      end do
     469                 :             : !    End of test nstopped/=0
     470                 :             :    end if
     471                 :             : 
     472                 :             : !  End of test ionmov==7
     473                 :             :  end if
     474                 :             : 
     475                 :             : !write(std_out,*) 'verlet 07'
     476                 :             : !##########################################################
     477                 :             : !### 07. Shift the data from next values to the present
     478                 :             : 
     479                 :             : !acell(:)=acell_next(:)
     480                 :             : !rprim(:,:)=rprim_next(:,:)
     481                 :             : !ucvol=ucvol_next
     482   [ +  +  +  + ]:         432 :  vel_prevhalf(:,:)=vel_nexthalf(:,:)
     483         [ +  + ]:         336 :  vin_prev(:)=vin(:)
     484         [ +  + ]:         336 :  vin(:)=vin_next(:)
     485   [ +  +  +  + ]:         432 :  xcart(:,:)=xcart_next(:,:)
     486   [ +  +  +  + ]:         432 :  xred(:,:)=xred_next(:,:)
     487                 :             : 
     488                 :          48 :  write(std_out,*) 'Shifted data EXIT'
     489                 :          48 :  write(std_out,*) 'acell(:)',acell(:)
     490                 :          48 :  write(std_out,*) 'rprim(:,:)',rprim(:,:)
     491                 :          48 :  write(std_out,*) 'rprimd(:,:)',rprimd(:,:)
     492                 :          48 :  write(std_out,*) 'ucvol',ucvol
     493                 :          48 :  write(std_out,*) 'vel_prevhalf(:,:)',vel_prevhalf(:,:)
     494                 :          48 :  write(std_out,*) 'vin_prev(:)',vin_prev(:)
     495                 :          48 :  write(std_out,*) 'vin(:)',vin(:)
     496                 :          48 :  write(std_out,*) 'xred(:,:)',xred(:,:)
     497                 :             : 
     498                 :             : 
     499                 :             : !write(std_out,*) 'verlet 08'
     500                 :             : !##########################################################
     501                 :             : !### 08. Update the history with the prediction
     502                 :             : 
     503                 :             : !Increase indexes
     504                 :          48 :  hist%ihist=abihist_findIndex(hist,+1)
     505                 :             : 
     506                 :             : !Fill the history with the variables
     507                 :             : !xred, acell, rprimd, vel
     508                 :          48 :  call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     509   [ +  +  +  + ]:         432 :  hist%vel(:,:,hist%ihist)=vel(:,:)
     510                 :          48 :  hist%time(hist%ihist)=real(itime,kind=dp)*ab_mover%dtion
     511                 :             : 
     512         [ -  + ]:          48 :  if(zDEBUG)then
     513                 :           0 :    write (std_out,*) 'vel:'
     514         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     515                 :           0 :      write (std_out,*) vel(:,kk)
     516                 :             :    end do
     517                 :             :  end if
     518                 :             : 
     519                 :             :  if (.false.) write(std_out,*) ntime
     520                 :             : 
     521                 :             : end subroutine pred_verlet
     522                 :             : !!***
     523                 :             : 
     524                 :             : end module m_pred_verlet
     525                 :             : !!***
        

Generated by: LCOV version 2.3-1