LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_pred_moldyn.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.1 % 130 121
Test Date: 2026-11-09 20:57:54 Functions: 100.0 % 1 1
Branches: 71.0 % 124 88

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_pred_moldyn
       2                 :             : !! NAME
       3                 :             : !!  m_pred_moldyn
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! COPYRIGHT
       8                 :             : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, 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_moldyn
      22                 :             : 
      23                 :             :  use defs_basis
      24                 :             :  use m_abicore
      25                 :             :  use m_abimover
      26                 :             :  use m_abihist
      27                 :             : 
      28                 :             :  use m_geometry,  only : xcart2xred, xred2xcart
      29                 :             :  use m_predtk,    only : fdtion
      30                 :             : 
      31                 :             :  implicit none
      32                 :             : 
      33                 :             :  private
      34                 :             : !!***
      35                 :             : 
      36                 :             :  public :: pred_moldyn
      37                 :             : !!***
      38                 :             : 
      39                 :             : contains
      40                 :             : !!***
      41                 :             : 
      42                 :             : !!****f* ABINIT/pred_moldyn
      43                 :             : !! NAME
      44                 :             : !! pred_moldyn
      45                 :             : !!
      46                 :             : !! FUNCTION
      47                 :             : !! Ionmov predictor (1) Molecular dynamics
      48                 :             : !!
      49                 :             : !! Molecular dynamics, with or without viscous damping
      50                 :             : !! This function should be called after the call to scfcv
      51                 :             : !! Updates positions, velocities and forces
      52                 :             : !!
      53                 :             : !! INPUTS
      54                 :             : !! ab_mover<type abimover>=Subset of dtset only related with
      55                 :             : !!          |                 movement of ions and acell, contains:
      56                 :             : !!          | dtion:  Time step
      57                 :             : !!          ! natom:  Number of atoms
      58                 :             : !!          | vis:    viscosity
      59                 :             : !!          | iatfix: Index of atoms and directions fixed
      60                 :             : !!          | amass:  Mass of ions
      61                 :             : !! icycle: Index of the internal cycle inside a time step (itime)
      62                 :             : !! itime: Index of time iteration
      63                 :             : !! zDEBUG : if true print some debugging information
      64                 :             : !!
      65                 :             : !! OUTPUT
      66                 :             : !!
      67                 :             : !! SIDE EFFECTS
      68                 :             : !! hist<type abihist>=Historical record of positions, forces,
      69                 :             : !!                               stresses, cell and energies,
      70                 :             : !!
      71                 :             : !! ncycle: Number of cycles of a particular time step
      72                 :             : !!
      73                 :             : !! NOTES
      74                 :             : !! * This routine is a predictor, it only produces new positions
      75                 :             : !!   to be computed in the next iteration, this routine should
      76                 :             : !!   produce not output at all
      77                 :             : !! * ncycle changes from 4 for the first iteration (itime==1) to 1 for (itime>1)
      78                 :             : !! * The arrays vec_tmp1 and vec_tmp2 are triky, they are use with
      79                 :             : !!   different meanings, during the initialization they contains
      80                 :             : !!   working positions and velocities that acumulated produce the
      81                 :             : !!   first positions of itime=1, for itime>1 they will contain
      82                 :             : !!   positions in 2 previous steps, those values are different
      83                 :             : !!   from the values store in the history, thats the reason why
      84                 :             : !!   we cannot simply use hist%xred to obtain those positions.
      85                 :             : !!
      86                 :             : !! SOURCE
      87                 :             : 
      88                 :          73 : subroutine pred_moldyn(ab_mover,hist,icycle,itime,ncycle,ntime,zDEBUG,iexit)
      89                 :             : 
      90                 :             : !Arguments ------------------------------------
      91                 :             : !scalars
      92                 :             : type(abimover),intent(in)       :: ab_mover
      93                 :             : type(abihist),intent(inout),target :: hist
      94                 :             : integer,intent(in)    :: icycle
      95                 :             : integer,intent(inout) :: ncycle
      96                 :             : integer,intent(in)    :: itime
      97                 :             : integer,intent(in)    :: ntime
      98                 :             : integer,intent(in)    :: iexit
      99                 :             : logical,intent(in)    :: zDEBUG
     100                 :             : 
     101                 :             : !Local variables-------------------------------
     102                 :             : !scalars
     103                 :             : integer  :: kk,jj,ihist,ihist_next,ihist_prev,ihist_prev2
     104                 :             : integer  :: ihist_prev4,ihist_prev5
     105                 :             : real(dp) :: aa,alfa,bb,cc,x0,xm,em,vis,dx,dv
     106                 :             : real(dp) :: fcart,fprev,fprev2
     107                 :             : real(dp) :: xc
     108                 :             : real(dp) :: vel,vnow,xnow,vprev
     109                 :             : real(dp),save :: hh,time
     110                 :             : !arrays
     111                 :             : real(dp) :: acell(3),rprimd(3,3)
     112                 :           6 : real(dp) :: xred(3,ab_mover%natom)
     113                 :          73 : real(dp),allocatable :: xcart(:,:),xcart_prev(:,:)
     114                 :             : real(dp),save,allocatable :: vec_tmp1(:,:)
     115                 :             : real(dp),save,allocatable :: vec_tmp2(:,:)
     116                 :          73 : real(dp), ABI_CONTIGUOUS pointer :: vel_cur(:,:),vel_next(:,:)
     117                 :          73 : real(dp),pointer :: fcart_cur(:,:),fcart_prev(:,:),fcart_prev2(:,:)
     118                 :             : 
     119                 :             : !***************************************************************************
     120                 :             : !Beginning of executable session
     121                 :             : !***************************************************************************
     122                 :             : 
     123                 :          73 :  if(iexit/=0)then
     124         [ +  - ]:           6 :    if(allocated(vec_tmp1))  then
     125                 :           6 :      ABI_FREE(vec_tmp1)
     126                 :             :    end if
     127         [ +  - ]:           6 :    if(allocated(vec_tmp2))  then
     128                 :           6 :      ABI_FREE(vec_tmp2)
     129                 :             :    end if
     130                 :             :    return
     131                 :             :  end if
     132                 :             : 
     133                 :          67 :  vis= ab_mover%vis
     134                 :             : !Just to avoid warnings of uninitialized variables
     135                 :             :  fprev=0.0_dp
     136                 :          67 :  fprev=0.0_dp
     137                 :          67 :  fprev2=0.0_dp
     138                 :          67 :  vnow=0.0_dp
     139                 :          67 :  vprev=0.0_dp
     140                 :          67 :  xnow=0.0_dp
     141                 :             : 
     142                 :             : !Those arrays contains intermediary results used with
     143                 :             : !different meanings during the different time steps
     144                 :             : !We need to preserv the allocation status, this is the
     145                 :             : !reason to be 'SAVE'
     146   [ +  +  +  + ]:          67 :  if (itime==1.and.icycle==1)then
     147         [ -  + ]:           6 :    if(allocated(vec_tmp1))  then
     148                 :           0 :      ABI_FREE(vec_tmp1)
     149                 :             :    end if
     150         [ -  + ]:           6 :    if(allocated(vec_tmp2))  then
     151                 :           0 :      ABI_FREE(vec_tmp2)
     152                 :             :    end if
     153   [ -  +  +  -  :          18 :    ABI_MALLOC(vec_tmp1,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     154   [ -  +  +  -  :          12 :    ABI_MALLOC(vec_tmp2,(3,ab_mover%natom))
          -  +  -  +  -  
                      + ]
     155                 :             :  end if
     156                 :             : 
     157                 :             : !write(std_out,*) '00'
     158                 :             : !##########################################################
     159                 :             : !### 00. Copy from the history to the variables
     160                 :             : 
     161                 :          67 :  call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     162                 :             : 
     163   [ -  +  +  -  :         201 :  ABI_MALLOC(xcart,(3,ab_mover%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     164                 :          67 :  call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
     165                 :             : 
     166         [ +  + ]:          67 :  if (itime==1.or.itime==2)then
     167   [ -  +  +  -  :          90 :    ABI_MALLOC(xcart_prev,(3,ab_mover%natom))
          +  -  +  -  -  
                +  -  + ]
     168                 :          30 :    call xred2xcart(ab_mover%natom,rprimd,xcart_prev,hist%xred(:,:,1))
     169                 :             :  end if
     170                 :             : 
     171                 :          67 :  ihist = abihist_findIndex(hist, 0)
     172                 :          67 :  ihist_prev  = abihist_findIndex(hist,-1)
     173                 :          67 :  ihist_prev2 = abihist_findIndex(hist,-2)
     174                 :          67 :  ihist_prev4 = abihist_findIndex(hist,-4)
     175                 :          67 :  ihist_prev5 = abihist_findIndex(hist,-5)
     176                 :          67 :  ihist_next  = abihist_findIndex(hist,+1)
     177                 :             : 
     178                 :          67 :  fcart_cur => hist%fcart(:,:,ihist)
     179         [ +  + ]:          67 :  if (itime==2) fcart_prev  => hist%fcart(:,:,ihist_prev4)
     180         [ +  + ]:          67 :  if (itime==3) fcart_prev2 => hist%fcart(:,:,ihist_prev5)
     181   [ +  +  +  + ]:          67 :  if (itime >2.or. icycle>=2)fcart_prev  => hist%fcart(:,:,ihist_prev)
     182   [ +  +  +  + ]:          67 :  if (itime >3.or. icycle>=3)fcart_prev2 => hist%fcart(:,:,ihist_prev2)
     183                 :             : 
     184                 :          67 :  vel_cur  => hist%vel(:,:,ihist)
     185                 :          67 :  vel_next => hist%vel(:,:,ihist_next)
     186                 :             : 
     187                 :             : !write(std_out,*) '01'
     188                 :             : !##########################################################
     189                 :             : !### 01. Get or compute the time step dtion
     190                 :             : 
     191         [ +  - ]:          67 :  if (ab_mover%dtion>0)then
     192                 :          67 :    hh = ab_mover%dtion
     193                 :             :  else
     194                 :           0 :    hh=fdtion(ab_mover,itime,xcart,fcart_cur,vel_cur)
     195                 :             :  end if
     196                 :             : 
     197                 :             : !write(std_out,*) '02'
     198                 :             : !##########################################################
     199                 :             : !### 02. For all atoms and directions
     200         [ +  + ]:         366 :  do kk=1,ab_mover%natom
     201                 :         299 :    em=ab_mover%amass(kk)
     202         [ +  + ]:        1263 :    do jj=1,3
     203                 :             : 
     204                 :             : !    write(std_out,*) '03'
     205                 :             : !    ##########################################################
     206                 :             : !    ### 03. Filling other values from history (forces and vel)
     207                 :         897 :      fcart=fcart_cur(jj,kk)
     208                 :         897 :      xc=xcart(jj,kk)
     209                 :         897 :      vel=hist%vel(jj,kk,1)
     210                 :             : 
     211                 :             : !    Previous values only after first iteration
     212   [ +  +  +  + ]:         897 :      if (itime>=2.or.icycle>=2) then
     213                 :         813 :        fprev=fcart_prev(jj,kk)
     214                 :         813 :        vprev=hist%vel(jj,kk,hist%ihist)
     215                 :             :      end if
     216   [ +  +  +  + ]:         897 :      if (itime>=3.or.icycle>=3) then
     217                 :         645 :        fprev2=fcart_prev2(jj,kk)
     218                 :             :      end if
     219                 :             : 
     220         [ +  + ]:         897 :      if (itime==2)then
     221                 :          84 :        vec_tmp1(jj,kk)=xcart_prev(jj,kk)
     222                 :          84 :        vec_tmp2(jj,kk)=xcart(jj,kk)
     223                 :             :      end if
     224                 :             : 
     225                 :             : !    write(std_out,*) '04'
     226                 :             : !    ##########################################################
     227                 :             : !    ### 04. Take first the atoms that are not allowed to move along
     228                 :             : !    ###     this direction
     229                 :             : !    ###     Warning : implemented in cartesian coordinates
     230         [ +  + ]:         897 :      if (ab_mover%iatfix(jj,kk)==1) then
     231                 :             : !      Their positions will be the same as xcart
     232                 :         445 :        xnow=xcart(jj,kk)
     233                 :             : !      Their velocities are zero
     234                 :         445 :        vnow=0.0_dp
     235                 :             :      else
     236                 :             : 
     237                 :             : !      write(std_out,*) '05'
     238                 :             : !      ##########################################################
     239                 :             : !      ### 05. Initialization (itime==1):
     240                 :             : !      ###     4 calls to obtain the forces are neeeded
     241                 :             : !      ###     The variables vec_tmp2 and vec_tmp1 from previous
     242                 :             : !      ###     calls are used in the following ones.
     243         [ +  + ]:         452 :        if(itime==1)then
     244                 :         152 :          x0=xcart_prev(jj,kk)
     245                 :             : 
     246                 :             : !        Prepare the second cycle
     247         [ +  + ]:         152 :          if(icycle==1)then
     248                 :          38 :            dx=hh*vel
     249                 :          38 :            dv=hh/em*(fcart-vis*vel)
     250                 :          38 :            xnow=x0+.5_dp*dx
     251                 :          38 :            vnow=vel+.5_dp*dv
     252                 :          38 :            vec_tmp2(jj,kk)=xc+sixth*dx
     253                 :          38 :            vec_tmp1(jj,kk)=vel+sixth*dv
     254         [ +  + ]:         114 :          else if(icycle==2)then
     255                 :          38 :            dx=hh*vprev
     256                 :          38 :            dv=hh/em*(fcart-vis*vprev)
     257                 :          38 :            xnow=x0+.5_dp*dx
     258                 :          38 :            vnow=vel+.5_dp*dv
     259                 :          38 :            vec_tmp2(jj,kk)=vec_tmp2(jj,kk)+third*dx
     260                 :          38 :            vec_tmp1(jj,kk)=vec_tmp1(jj,kk)+third*dv
     261         [ +  + ]:          76 :          else if(icycle==3)then
     262                 :          38 :            dx=hh*vprev
     263                 :          38 :            dv=hh/em*(fcart-vis*vprev)
     264                 :          38 :            xnow=x0+dx
     265                 :          38 :            vnow=vel+dv
     266                 :          38 :            vec_tmp2(jj,kk)=vec_tmp2(jj,kk)+third*dx
     267                 :          38 :            vec_tmp1(jj,kk)=vec_tmp1(jj,kk)+third*dv
     268         [ +  - ]:          38 :          else if(icycle==4)then
     269                 :          38 :            dx=hh*vprev
     270                 :          38 :            dv=hh/em*(fcart-vis*vprev)
     271                 :          38 :            xnow=vec_tmp2(jj,kk)+sixth*dx
     272                 :          38 :            vnow=vec_tmp1(jj,kk)+sixth*dv
     273                 :             :          end if
     274                 :             :        else !(itime/=1)
     275                 :             : 
     276                 :             : !        write(std_out,*) '06'
     277                 :             : !        ##########################################################
     278                 :             : !        ### 06. Change positions and velocities
     279                 :             : !        ###     These changes only applies for itime>2
     280         [ +  + ]:         300 :          if (itime>2)then
     281                 :             : !          Uses a corrector to have better value of xnow, and
     282                 :             : !          derive vnow. Only update atoms position and
     283                 :             : !          velocity along its allowed directions
     284                 :         262 :            aa=fprev
     285                 :         262 :            bb=(fcart-fprev2)/(2._dp*hh)
     286                 :         262 :            cc=(fcart+fprev2-2._dp*fprev)/(2._dp*hh*hh)
     287                 :         262 :            x0=vec_tmp2(jj,kk)
     288                 :         262 :            xm=vec_tmp1(jj,kk)
     289         [ -  + ]:         262 :            if(abs(vis)<=1.d-8)then
     290                 :             : !            NON-DAMPED DYNAMICS (Post-Code)
     291                 :             :              xnow=2._dp*x0-xm+hh**2/em/12._dp*&
     292                 :           0 : &             (fprev2+10._dp*fprev+fcart)
     293                 :             :              vnow=(bb*hh**2)/(3._dp*em)&
     294                 :             : &             +1.5_dp*aa*hh/em+&
     295                 :             : &             (5._dp/12._dp)*cc*hh**3/em&
     296                 :           0 : &             +x0/hh-xm/hh
     297                 :             :            else
     298                 :             : !            DAMPED DYNAMICS (Post-Code)
     299                 :         262 :              alfa=exp(-vis*hh/em)
     300                 :             :              xnow=((-aa*hh*vis**2+0.5_dp*bb*hh**2*vis**2&
     301                 :             : &             -third*cc*hh**3*vis**2+em*bb*hh*vis&
     302                 :             : &             -em*cc*hh**2*vis-2._dp*em**2*cc*hh+x0*vis**3-xm*vis**3)*alfa&
     303                 :             : &             +aa*hh*vis**2-em*bb*hh*vis+third*cc*hh**3*vis**2&
     304                 :             : &             +2._dp*em**2*cc*hh+0.5D0*bb*hh**2*vis**2-em*cc*hh**2*vis+x0*vis**3)&
     305                 :         262 : &             /vis**3
     306                 :             :              vnow=(em*aa*vis**2*alfa-em*aa*vis**2+bb*hh*vis**2*em*alfa&
     307                 :             : &             -bb*hh*vis**2*em+cc*hh**2*vis**2*em*alfa-cc*hh**2*vis**2*em&
     308                 :             : &             -em**2*bb*vis*alfa+em**2*bb*vis-2._dp*em**2*cc*hh*vis*alfa+&
     309                 :             : &             2._dp*em**2*cc*hh*vis+2._dp*em**3*cc*alfa-2._dp*em**3*cc+&
     310                 :             : &             vis**3*alfa**2*aa*hh-0.5_dp*vis**3*alfa**2*bb*hh**2+&
     311                 :             : &             third*vis**3*alfa**2*cc*hh**3-vis**2*&
     312                 :             : &             alfa**2*em*bb*hh+vis**2*alfa**2*em*cc*hh**2+&
     313                 :             : &             2._dp*vis*alfa**2*em**2*cc*hh-vis**4*alfa**2*x0+&
     314                 :         262 : &             vis**4*alfa**2*xm)/vis**3/(alfa-1._dp)/em
     315                 :             : 
     316                 :             :            end if !if(abs(vis)<=1.d-8)
     317                 :             : 
     318                 :         262 :            xc=xnow
     319                 :         262 :            vec_tmp1(jj,kk)=vec_tmp2(jj,kk)
     320                 :         262 :            vec_tmp2(jj,kk)=xnow
     321                 :             :          else
     322                 :             :            vnow=vprev
     323                 :             :          end if !if(itime>2)
     324                 :             : 
     325                 :             : !        write(std_out,*) '07'
     326                 :             : !        ##########################################################
     327                 :             : !        ### 07. Correct positions
     328                 :             : !        ###     These changes only applies for itime>1
     329                 :             : 
     330         [ -  + ]:         300 :          if(abs(vis)<=1.d-8)then
     331                 :             : !          NON-DAMPED DYNAMICS (Pre-Code)
     332                 :             : !          If the viscosity is too small, the equations become
     333                 :             : !          ill conditioned due to rounding error so do regular
     334                 :             : !          Verlet predictor Numerov corrector.
     335                 :           0 :            x0=vec_tmp2(jj,kk)
     336                 :           0 :            xm=vec_tmp1(jj,kk)
     337                 :             :            xnow=2._dp*x0-xm&
     338                 :           0 : &           + hh**2/em*fcart
     339                 :             :          else
     340                 :             : !          DAMPED DYNAMICS (Pre-Code)
     341                 :             : !          These equations come from solving
     342                 :             : !          m*d2x/dt2+vis*dx/dt=a+b*t+c*t**2
     343                 :             : !          analytically under the boundary conditions that
     344                 :             : !          x(0)=x0 and x(-h)=xm, and the following is the
     345                 :             : !          expression for x(h). a, b and c are determined
     346                 :             : !          from our knowledge of the driving forces.
     347                 :         300 :            aa=fcart
     348                 :         300 :            bb=(fcart-fprev)/hh
     349                 :         300 :            x0=vec_tmp2(jj,kk)
     350                 :         300 :            xm=vec_tmp1(jj,kk)
     351                 :         300 :            alfa=exp(-vis*hh/em)
     352                 :             :            xnow=( (-aa*hh*vis**2 +0.5_dp*bb*hh**2*vis**2&
     353                 :             : &           +em*bb*hh*vis +x0*vis**3 -xm*vis**3)*alfa&
     354                 :             : &           +aa*hh*vis**2 -em*bb*hh*vis&
     355                 :         300 : &           +0.5_dp*bb*hh**2*vis**2 +x0*vis**3)/vis**3
     356                 :             : !          End of choice between initialisation, damped
     357                 :             : !          dynamics and non-damped dynamics
     358                 :             :          end if
     359                 :             : 
     360                 :             :        end if !if(itime==1)
     361                 :             : 
     362                 :             :      end if !if(ab_mover%iatfix(jj,kk)==1)
     363                 :             : 
     364                 :             : !    write(std_out,*) '08'
     365                 :             : !    ##########################################################
     366                 :             : !    ### 08. Update history
     367                 :             : 
     368                 :         897 :      xcart(jj,kk)=xnow
     369                 :        1196 :      vel_next(jj,kk)=vnow
     370                 :             : 
     371                 :             : !    write(std_out,*) '09'
     372                 :             : !    ##########################################################
     373                 :             : !    ### 09. End loops of atoms and directions
     374                 :             :    end do ! jj=1,3
     375                 :             :  end do ! kk=1,ab_mover%natom
     376                 :             : 
     377                 :             : !write(std_out,*) '10'
     378                 :             : !##########################################################
     379                 :             : !### 10. Filling history with the new values
     380                 :             : 
     381                 :          67 :  hist%ihist = abihist_findIndex(hist,+1)
     382                 :             : 
     383                 :          67 :  call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
     384                 :          67 :  call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     385                 :             : 
     386                 :             : !Change ncycle for itime>1
     387         [ +  + ]:          67 :  if (icycle==4)  ncycle=1
     388                 :             : 
     389         [ +  + ]:          67 :  if (itime==1)then
     390                 :          24 :    time=0.0_dp
     391         [ -  + ]:          24 :    if (ab_mover%dtion<0)then
     392                 :           0 :      write(std_out,*) 'Time=',time
     393                 :             :    end if
     394                 :             :  end if
     395                 :          67 :  time=time+hh
     396                 :          67 :  hist%time(hist%ihist)=time
     397                 :             : 
     398         [ +  - ]:          67 :  ABI_SFREE(xcart)
     399         [ +  + ]:          67 :  ABI_SFREE(xcart_prev)
     400                 :             : 
     401                 :             :  if (.false.) write(std_out,*) ntime
     402                 :             : 
     403   [ +  +  -  + ]:         140 : end subroutine pred_moldyn
     404                 :             : !!***
     405                 :             : 
     406                 :             : end module m_pred_moldyn
     407                 :             : !!***
        

Generated by: LCOV version 2.3-1