LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_pred_delocint.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.4 % 562 424
Test Date: 2026-11-10 15:53:16 Functions: 92.3 % 13 12
Branches: 49.7 % 966 480

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_pred_delocint
       2                 :             : !! NAME
       3                 :             : !! m_pred_delocint
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! COPYRIGHT
       8                 :             : !!  Copyright (C) 1998-2026 ABINIT group (MVer, 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_delocint
      22                 :             : 
      23                 :             :  use defs_basis
      24                 :             :  use m_errors
      25                 :             :  use m_abicore
      26                 :             :  use m_abimover
      27                 :             :  use m_abihist
      28                 :             :  use m_xfpack
      29                 :             :  use m_linalg_interfaces
      30                 :             : 
      31                 :             :  use m_geometry,   only : fcart2gred, xcart2xred, xred2xcart, metric, acrossb
      32                 :             :  use m_bfgs,       only : hessinit, hessupdt, brdene
      33                 :             :  use m_results_gs, only : results_gs_type
      34                 :             : 
      35                 :             :  implicit none
      36                 :             : 
      37                 :             :  private
      38                 :             : !!***
      39                 :             : 
      40                 :             :  public :: pred_delocint
      41                 :             : 
      42                 :             : contains
      43                 :             : !!***
      44                 :             : 
      45                 :             : !!****f* ABINIT/pred_delocint
      46                 :             : !! NAME
      47                 :             : !! pred_delocint
      48                 :             : !!
      49                 :             : !! FUNCTION
      50                 :             : !! Ionmov predictors (10) BFGS with delocalized internal coordinates
      51                 :             : !!
      52                 :             : !! IONMOV 10:
      53                 :             : !! Given a starting point xred that is a vector of length 3*(natom-1)
      54                 :             : !! (reduced nuclei coordinates),
      55                 :             : !! and unit cell parameters (acell and rprimd) the
      56                 :             : !! Broyden-Fletcher-Goldfarb-Shanno minimization is performed on the
      57                 :             : !! total energy function, using its gradient (atomic forces and stresses)
      58                 :             : !  as calculated by the routine scfcv. Some atoms can be kept fixed,
      59                 :             : !! while the optimization of unit cell
      60                 :             : !! parameters is only performed if optcell/=0.
      61                 :             : !! The convergence requirement on
      62                 :             : !! the atomic forces, 'tolmxf',  allows an early exit.
      63                 :             : !! Otherwise no more than 'ntime' steps are performed.
      64                 :             : !! Returned quantities are xred, and eventually acell and rprimd (new ones!).
      65                 :             : !! Could see Numerical Recipes (Fortran), 1986, page 307.
      66                 :             : !!
      67                 :             : !!  Implements the delocalized internal coordinate scheme
      68                 :             : !!  of Andzelm et al. in CPL .335. 321 (2001) \
      69                 :             : !!  and Baker et al. JCP .105. 192 (1996)
      70                 :             : !!
      71                 :             : !!    B matrix is derivative of delocalized internals wrt cartesian coordinates
      72                 :             : !!    U matrix is eigenvectors of G = B*B^{T}
      73                 :             : !!    S matrix is eigenvectors of F = B^{T}B
      74                 :             : !!
      75                 :             : !! INPUTS
      76                 :             : !! ab_mover <type(abimover)> : Datatype with all the information needed by the preditor
      77                 :             : !! itime  : Index of the present iteration
      78                 :             : !! ntime  : Maximal number of iterations
      79                 :             : !! ionmov : (10 or 11) Specific kind of BFGS
      80                 :             : !! zDEBUG : if true print some debugging information
      81                 :             : !!
      82                 :             : !! OUTPUT
      83                 :             : !!
      84                 :             : !! SIDE EFFECTS
      85                 :             : !! hist <type(abihist)> : History of positions,forces acell, rprimd, stresses
      86                 :             : !!
      87                 :             : !! SOURCE
      88                 :             : 
      89                 :           2 : subroutine pred_delocint(ab_mover,ab_xfh,deloc,forstr,hist,ionmov,itime,zDEBUG,iexit)
      90                 :             : 
      91                 :             : !Arguments ------------------------------------
      92                 :             : !scalars
      93                 :             :  type(abimover),intent(in)       :: ab_mover
      94                 :             :  type(ab_xfh_type),intent(inout)    :: ab_xfh
      95                 :             :  type(abihist),intent(inout) :: hist
      96                 :             :  type(abiforstr),intent(in) :: forstr
      97                 :             :  type(delocint),intent(inout) :: deloc
      98                 :             :  integer,intent(in) :: itime
      99                 :             :  integer,intent(in) :: ionmov
     100                 :             :  integer,intent(in) :: iexit
     101                 :             :  logical,intent(in) :: zDEBUG
     102                 :             : 
     103                 :             : !Local variables-------------------------------
     104                 :             : !scalars
     105                 :             :  integer  :: ndim,cycl_main
     106                 :             :  integer  :: ihist_prev,ii,jj,kk
     107                 :             :  real(dp),save :: ucvol0
     108                 :             :  real(dp) :: ucvol
     109                 :             :  real(dp) :: etotal,etotal_prev
     110                 :             :  logical  :: DEBUG=.TRUE.
     111                 :             :  !integer,save :: icenter,irshift ! DELOCINT indexes
     112                 :             :  integer,save :: ndeloc ! DELOCINT number of
     113                 :             :  character(len=500) :: message
     114                 :             : 
     115                 :             : !arrays
     116                 :             :  real(dp),allocatable,save :: hessin(:,:),vin(:),vin_prev(:)
     117                 :             :  real(dp),allocatable,save :: vout(:),vout_prev(:)
     118                 :             :  real(dp),save :: acell0(3) ! Initial acell
     119                 :             :  real(dp),save :: rprimd0(3,3) ! Initial rprimd
     120                 :           2 :  real(dp),allocatable :: prim_int(:)
     121                 :             :  real(dp),allocatable,save :: u_matrix(:,:) ! DELOCINT this may need to be added to type inside ab_mover
     122                 :             :  real(dp) :: acell(3)
     123                 :             :  real(dp) :: rprimd(3,3)
     124                 :             :  real(dp) :: gprimd(3,3)
     125                 :             :  real(dp) :: gmet(3,3)
     126                 :             :  real(dp) :: rmet(3,3)
     127                 :           4 :  real(dp) :: residual(3,ab_mover%natom)
     128                 :             : !real(dp) :: residual_corrected(3,ab_mover%natom)
     129                 :           4 :  real(dp) :: xred(3,ab_mover%natom),xcart(3,ab_mover%natom)
     130                 :             :  real(dp) :: strten(6)
     131                 :           4 :  real(dp) :: deloc_gred(3*(ab_mover%natom-1))
     132                 :           4 :  real(dp) :: deloc_int(3*(ab_mover%natom-1))
     133                 :           2 :  real(dp) :: bt_inv_matrix(3*(ab_mover%natom-1),3*ab_mover%natom)
     134                 :             : 
     135                 :             : !***************************************************************************
     136                 :             : !Beginning of executable session
     137                 :             : !***************************************************************************
     138                 :             : 
     139         [ +  + ]:           2 :  if(iexit/=0)then
     140         [ +  - ]:           1 :    ABI_SFREE(vin)
     141         [ +  - ]:           1 :    ABI_SFREE(vout)
     142         [ +  - ]:           1 :    ABI_SFREE(vin_prev)
     143         [ +  - ]:           1 :    ABI_SFREE(vout_prev)
     144         [ +  - ]:           1 :    ABI_SFREE(hessin)
     145         [ +  - ]:           1 :    ABI_SFREE(u_matrix)
     146                 :             :    return
     147                 :             :  end if
     148                 :             : 
     149                 :             : !write(std_out,*) 'delocint 01'
     150                 :             : !##########################################################
     151                 :             : !### 01. Debugging and Verbose
     152                 :             : 
     153         [ +  - ]:           1 :  if(DEBUG)then
     154   [ +  -  +  +  :          43 :    write(std_out,'(a,3a,38a,39a)') ch10,('-',kk=1,3),'Debugging and Verbose for pred_deloint',('-',kk=1,39)
             +  -  +  + ]
     155                 :           1 :    write(std_out,*) 'ionmov: ',ionmov
     156                 :           1 :    write(std_out,*) 'itime:  ',itime
     157                 :             :  end if
     158                 :             : 
     159                 :             : !write(std_out,*) 'delocint 02'
     160                 :             : !##########################################################
     161                 :             : !### 02. Compute the dimension of vectors (ndim)
     162                 :             : 
     163                 :             : !With internal we have 1 coordinate less
     164                 :           1 :  ndeloc = 3*(ab_mover%natom-1)
     165                 :           1 :  ndim=ndeloc
     166         [ +  + ]:           4 :  deloc_int(:)=zero
     167         [ +  + ]:           4 :  deloc_gred(:)=zero
     168         [ -  + ]:           1 :  if(ab_mover%optcell==1) ndim=ndim+1
     169         [ -  + ]:           1 :  if(ab_mover%optcell==2 .or.&
     170                 :           0 : & ab_mover%optcell==3) ndim=ndim+6
     171         [ -  + ]:           1 :  if(ab_mover%optcell>=4) ndim=ndim+3
     172                 :             : 
     173         [ +  - ]:           1 :  if(DEBUG) write(std_out,*) 'Dimension of vin, vout and hessian (ndim): ',ndim
     174                 :             : 
     175                 :             : !write(std_out,*) 'delocint 03'
     176                 :             : !##########################################################
     177                 :             : !### 03. Allocate the vectors vin, vout and hessian matrix
     178                 :             : 
     179                 :             : !Notice thqt vin, vout, etc could be allocated
     180                 :             : !From a previous dataset with a different ndim
     181         [ +  - ]:           1 :  if(itime==1)then
     182         [ -  + ]:           1 :    ABI_SFREE(vin)
     183         [ -  + ]:           1 :    ABI_SFREE(vout)
     184         [ -  + ]:           1 :    ABI_SFREE(vin_prev)
     185         [ -  + ]:           1 :    ABI_SFREE(vout_prev)
     186         [ -  + ]:           1 :    ABI_SFREE(hessin)
     187                 :             : 
     188   [ -  +  +  -  :           3 :    ABI_MALLOC(vin,(ndim))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     189   [ -  +  +  -  :           2 :    ABI_MALLOC(vout,(ndim))
          -  +  -  +  -  
                      + ]
     190   [ -  +  +  -  :           2 :    ABI_MALLOC(vin_prev,(ndim))
          -  +  -  +  -  
                      + ]
     191   [ -  +  +  -  :           2 :    ABI_MALLOC(vout_prev,(ndim))
          -  +  -  +  -  
                      + ]
     192   [ -  +  +  -  :           4 :    ABI_MALLOC(hessin,(ndim,ndim))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     193                 :             :  end if
     194                 :             : 
     195                 :             : 
     196                 :             : !write(std_out,*) 'delocint 04'
     197                 :             : !##########################################################
     198                 :             : !### 04. Obtain the present values from the history
     199                 :             : 
     200                 :           1 :  call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     201                 :           1 :  call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
     202                 :             : 
     203         [ +  + ]:           7 :  strten(:)=hist%strten(:,hist%ihist)
     204                 :           1 :  etotal   =hist%etot(hist%ihist)
     205                 :             : 
     206                 :             : !Fill the residual with forces (No preconditioning)
     207                 :             : !Or the preconditioned forces
     208         [ +  - ]:           1 :  if (ab_mover%goprecon==0)then
     209                 :           1 :    call fcart2gred(hist%fcart(:,:,hist%ihist),residual,rprimd,ab_mover%natom)
     210                 :             :  else
     211   [ #  #  #  # ]:           0 :    residual(:,:)= forstr%gred(:,:)
     212                 :             :  end if
     213                 :             : 
     214         [ -  + ]:           1 :  if(zDEBUG)then
     215                 :           0 :    write (std_out,*) 'residual:'
     216         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     217                 :           0 :      write (std_out,*) residual(:,kk)
     218                 :             :    end do
     219                 :           0 :    write (std_out,*) 'strten:'
     220                 :           0 :    write (std_out,*) strten(1:3),ch10,strten(4:6)
     221                 :           0 :    write (std_out,*) 'etotal:'
     222                 :           0 :    write (std_out,*) etotal
     223                 :             :  end if
     224                 :             : 
     225                 :           1 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     226                 :             : 
     227                 :             : !Save initial values
     228         [ +  - ]:           1 :  if (itime==1)then
     229                 :           1 :    acell0(:)=acell(:)
     230                 :           1 :    rprimd0(:,:)=rprimd(:,:)
     231                 :           1 :    ucvol0=ucvol
     232                 :             :  end if
     233                 :             : 
     234                 :             : !DEBUG (UCVOL)
     235         [ +  - ]:           1 :  if(DEBUG)then
     236                 :           1 :    write(std_out,*) 'Volume of cell (ucvol):',ucvol
     237                 :             :  end if
     238                 :             : 
     239                 :             : !Get rid of mean force on whole unit cell, but only if no
     240                 :             : !generalized constraints are in effect
     241                 :             : !  residual_corrected(:,:)=residual(:,:)
     242                 :             : !  if(ab_mover%nconeq==0)then
     243                 :             : !    do ii=1,3
     244                 :             : !      if (ii/=3.or.ab_mover%jellslab==0) then
     245                 :             : !        favg=sum(residual_corrected(ii,:))/dble(ab_mover%natom)
     246                 :             : !        residual_corrected(ii,:)=residual_corrected(ii,:)-favg
     247                 :             : !      end if
     248                 :             : !    end do
     249                 :             : !  end if
     250                 :             : 
     251                 :             : !write(std_out,*) 'delocint 05'
     252                 :             : !##########################################################
     253                 :             : !### 05. Compute internals for first time
     254                 :             : 
     255         [ +  - ]:           1 :  if (itime==1)then
     256                 :             :    call make_prim_internals(deloc,ab_mover%natom,&
     257   [ +  -  -  -  :           1 : &   ab_mover%ntypat,rprimd,ab_mover%typat,xcart,ab_mover%znucl)
             -  -  -  + ]
     258                 :             : 
     259   [ -  +  +  -  :           3 :    ABI_MALLOC(prim_int,(deloc%ninternal))
          +  -  +  -  -  
                +  -  + ]
     260                 :             : 
     261         [ +  - ]:           1 :    if(DEBUG)then
     262                 :           1 :      write (message,'(a,i6)') 'Number of primitive internal coordinates (ninternal): ',deloc%ninternal
     263                 :           1 :      call wrtout(std_out,  message,'COLL')
     264                 :             :    end if
     265                 :             : 
     266         [ -  + ]:           1 :    if (allocated(u_matrix))  then
     267                 :           0 :      ABI_FREE(u_matrix)
     268                 :             :    end if
     269   [ -  +  +  -  :           4 :    ABI_MALLOC(u_matrix,(deloc%ninternal,ndeloc))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     270                 :             : 
     271                 :           1 :    call calc_prim_int(deloc,ab_mover%natom,rprimd,xcart,prim_int)
     272                 :             : 
     273         [ +  - ]:           1 :    if(DEBUG)then
     274                 :           1 :      write (message,'(a)') 'Primitive internal coordinate values:'
     275                 :           1 :      call wrtout(std_out,  message,'COLL')
     276                 :           1 :      write (message,'(a)') ' Bonds:'
     277                 :           1 :      call wrtout(std_out,  message,'COLL')
     278         [ +  + ]:           5 :      do ii = 1, deloc%nbond
     279                 :           4 :        write (message,'(i6,E20.10)') ii, prim_int(ii)
     280                 :           5 :        call wrtout(std_out,  message,'COLL')
     281                 :             :      end do
     282                 :             : 
     283                 :           1 :      write (message,'(a)') ' Angles:'
     284                 :           1 :      call wrtout(std_out,  message,'COLL')
     285         [ +  + ]:          13 :      do ii = deloc%nbond+1, deloc%nbond+deloc%nang
     286                 :          12 :        write (message,'(i6,2(E20.10,2x))') ii, prim_int(ii), prim_int(ii)/pi*180.0_dp
     287                 :          13 :        call wrtout(std_out,  message,'COLL')
     288                 :             :      end do
     289                 :             : 
     290                 :           1 :      write (message,'(a)') ' Dihedrals:'
     291                 :           1 :      call wrtout(std_out,  message,'COLL')
     292         [ +  + ]:          37 :      do ii = deloc%nbond+deloc%nang+1, deloc%nbond+deloc%nang+deloc%ndihed
     293                 :          36 :        write (message,'(i6,2(E20.10,2x))') ii, prim_int(ii), prim_int(ii)/pi*180.0_dp
     294                 :          37 :        call wrtout(std_out,  message,'COLL')
     295                 :             :      end do
     296                 :             : 
     297                 :           1 :      write (message,'(a)') ' Cartesian auxiliary coordinates for constraints:'
     298                 :           1 :      call wrtout(std_out,  message,'COLL')
     299         [ -  + ]:           1 :      do ii = deloc%nbond+deloc%nang+deloc%ndihed+1, deloc%ninternal
     300                 :           0 :        write (message,'(i6,E20.10)') ii, prim_int(ii)
     301                 :           1 :        call wrtout(std_out,  message,'COLL')
     302                 :             :      end do
     303                 :             :    end if
     304                 :             : 
     305         [ -  + ]:           1 :    ABI_FREE(prim_int)
     306                 :             : 
     307                 :             : !  equal weight on all internal coordinates as a starting point.
     308   [ +  +  +  + ]:         160 :    u_matrix(:,:) = one / dble (ndeloc)
     309                 :             : 
     310                 :             : !  Zero the arrays before first use
     311         [ +  + ]:           4 :    deloc_gred(:) = zero
     312                 :             : 
     313                 :             :  end if
     314                 :             : 
     315   [ -  +  +  -  :           3 :  ABI_MALLOC(prim_int,(deloc%ninternal))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     316                 :             : 
     317                 :             : !write(std_out,*) 'delocint 06'
     318                 :             : !##########################################################
     319                 :             : !### 06. Compute delocalized coordinates and forces
     320                 :             : 
     321                 :             : !xcart ---> deloc_int
     322                 :             : 
     323                 :             : !Convert positions to delocalized coordinates for next step
     324                 :             :  call xcart2deloc(deloc,ab_mover%natom,rprimd,xcart,&
     325                 :           1 : & bt_inv_matrix,u_matrix,deloc_int,prim_int)
     326                 :             : 
     327                 :             : !gred ---> deloc_gred
     328                 :             : 
     329                 :             : !Convert gradients to delocalized coordinates for next step
     330                 :           1 :  call gred2gdeloc(bt_inv_matrix,deloc_gred,residual,ab_mover%natom,gprimd)
     331                 :             : 
     332                 :             : !write(std_out,*) 'delocint 07'
     333                 :             : !##########################################################
     334                 :             : !### 07. Fill the vectors vin and vout
     335                 :             : 
     336                 :             : !DEBUG deloc_int and deloc_gred before pack
     337         [ +  - ]:           1 :  if(DEBUG)then
     338                 :           1 :    write (std_out,*) 'Delocalized internals and forces (ndeloc):',ndeloc
     339                 :           1 :    write(std_out,*) 'deloc_int'
     340   [ -  +  -  + ]:           2 :    do ii=1,ndeloc,3
     341         [ +  - ]:           2 :      if (ii+2<=ndeloc)then
     342                 :           1 :        write(std_out,*) ii,deloc_int(ii:ii+2)
     343                 :             :      else
     344                 :           0 :        write(std_out,*) ii,deloc_int(ii:ndeloc)
     345                 :             :      end if
     346                 :             :    end do
     347                 :           1 :    write(std_out,*) 'deloc_gred'
     348   [ -  +  -  + ]:           2 :    do ii=1,ndeloc,3
     349         [ +  - ]:           2 :      if (ii+2<=ndeloc)then
     350                 :           1 :        write(std_out,*) ii,deloc_gred(ii:ii+2)
     351                 :             :      else
     352                 :           0 :        write(std_out,*) ii,deloc_gred(ii:ndeloc)
     353                 :             :      end if
     354                 :             :    end do
     355                 :             :  end if
     356                 :             : 
     357                 :             : !DELOCINT
     358                 :             : !Instead of gred_corrected we use deloc_gred
     359                 :             : !Instead of xred e use deloc_int
     360                 :             : !
     361                 :             : !Initialize input vectors : first vin, then vout
     362                 :             : !The values of vin from the previous iteration
     363                 :             : !should be the same
     364                 :             :  call xfpack_x2vin(acell, ab_mover%natom-1, ndim,&
     365                 :             : & ab_mover%nsym, ab_mover%optcell, rprimd, rprimd0,&
     366   [ +  -  -  -  :           1 : & ab_mover%symrel, ucvol, ucvol0, vin, deloc_int)
          -  -  -  -  -  
                -  -  + ]
     367                 :             : !end if
     368                 :             : 
     369                 :             :  call xfpack_f2vout(deloc_gred, ab_mover%natom-1, ndim,&
     370                 :             : & ab_mover%optcell, ab_mover%strtarget, strten, ucvol, &
     371   [ +  -  -  -  :           1 : & vout)
             -  -  -  + ]
     372                 :             : 
     373                 :             : !write(std_out,*) 'delocint 08'
     374                 :             : !##########################################################
     375                 :             : !### 08. Initialize or update the hessian matrix
     376                 :             : 
     377                 :             : !Initialise the Hessian matrix using gmet
     378         [ +  - ]:           1 :  if (itime==1)then
     379                 :             : 
     380                 :             : !  Initialise the Hessian matrix with ab_mover%userrc.
     381                 :             : !  this has become unusable because it imposes ndim >= 3 natom
     382                 :             : !  ident = 3x3 identity matrix
     383                 :             : !  call hessinit(ab_mover, hessin, gmet, ndim, ucvol)
     384   [ +  +  +  + ]:          13 :    hessin = zero
     385         [ +  + ]:           4 :    do ii=1, ndim
     386                 :           4 :      hessin (ii,ii) = one
     387                 :             :    end do
     388                 :             : 
     389                 :             : !  ! Initialize inverse hessian with identity matrix
     390                 :             : !  ! in cartesian coordinates, which makes use of metric tensor gmet
     391                 :             : !  ! in reduced coordinates.
     392                 :             : !  hessin(:,:)=zero
     393                 :             : !  do ii=1,ab_mover%natom
     394                 :             : !  do kk=1,3
     395                 :             : !  do jj=1,3
     396                 :             : !  ! Warning : implemented in reduced coordinates
     397                 :             : !  if (ab_mover%iatfix(kk,ii)==0 .and.&
     398                 :             : !  & ab_mover%iatfix(jj,ii)==0 )then
     399                 :             : !  hessin(kk+3*(ii-1),jj+3*(ii-1))=gmet(kk,jj)
     400                 :             : !  end if
     401                 :             : !  end do
     402                 :             : !  end do
     403                 :             : !  end do
     404                 :             : !  if(ab_mover%optcell/=0)then
     405                 :             : !  ! These values might lead to too large changes in some cases
     406                 :             : !  diag=ab_mover%strprecon*30.0_dp/ucvol
     407                 :             : !  if(ab_mover%optcell==1) diag=diag/three
     408                 :             : !  do ii=3*ab_mover%natom+1,ndim
     409                 :             : !  hessin(ii,ii)=diag
     410                 :             : !  end do
     411                 :             : !  end if
     412                 :             : 
     413         [ -  + ]:           1 :    if (ab_mover%restartxf/=0) then
     414                 :             : 
     415                 :             :      call xfh_recover_deloc(ab_xfh,ab_mover,acell,cycl_main,&
     416                 :             : &     residual,hessin,ndim,rprimd,rprimd0,strten,ucvol,ucvol0,vin,vin_prev,&
     417                 :             : &     vout,vout_prev,xred,deloc,deloc_int,deloc_gred,bt_inv_matrix,gprimd,prim_int,&
     418                 :           0 : &     u_matrix)
     419                 :             : 
     420                 :             :    end if
     421                 :             : 
     422                 :             :  end if
     423                 :             : 
     424         [ -  + ]:           1 :  ABI_FREE(prim_int)
     425                 :             : 
     426         [ -  + ]:           1 :  if(itime>1)then
     427                 :             : !  Update the hessian matrix, by taking into account the
     428                 :             : !  current pair (x,f) and the previous one.
     429                 :             :    call hessupdt(hessin,ab_mover%iatfix,ab_mover%natom,ndim,vin,&
     430   [ #  #  #  #  :           0 : &   vin_prev,vout,vout_prev)
          #  #  #  #  #  
                      # ]
     431                 :             : 
     432                 :             :  end if
     433                 :             : 
     434                 :             : !DEBUG (vin,vout and hessin before prediction)
     435         [ +  - ]:           1 :  if(DEBUG)then
     436                 :           1 :    write(std_out,*) 'Vectors vin and vout and inverse of Hessian (hessin) [before]'
     437                 :           1 :    write(std_out,*) 'vin:'
     438   [ -  +  -  + ]:           2 :    do ii=1,ndim,3
     439         [ +  - ]:           2 :      if (ii+2<=ndim)then
     440                 :           1 :        write(std_out,*) ii,vin(ii:ii+2)
     441                 :             :      else
     442                 :           0 :        write(std_out,*) ii,vin(ii:ndim)
     443                 :             :      end if
     444                 :             :    end do
     445                 :           1 :    write(std_out,*) 'vout:'
     446   [ -  +  -  + ]:           2 :    do ii=1,ndim,3
     447         [ +  - ]:           2 :      if (ii+2<=ndim)then
     448                 :           1 :        write(std_out,*) ii,vout(ii:ii+2)
     449                 :             :      else
     450                 :           0 :        write(std_out,*) ii,vout(ii:ndim)
     451                 :             :      end if
     452                 :             :    end do
     453                 :           1 :    write(std_out,*) 'Inverse Hessian (hessin): ',ndim,'x',ndim
     454         [ +  + ]:           4 :    do kk=1,ndim
     455   [ -  +  -  + ]:           7 :      do jj=1,ndim,3
     456         [ +  - ]:           6 :        if (jj+2<=ndim)then
     457                 :           3 :          write(std_out,*) jj,hessin(jj:jj+2,kk)
     458                 :             :        else
     459                 :           0 :          write(std_out,*) jj,hessin(jj:ndim,kk)
     460                 :             :        end if
     461                 :             :      end do
     462                 :             :    end do
     463                 :             :  end if
     464                 :             : 
     465                 :             : !write(std_out,*) 'delocint 09'
     466                 :             : !##########################################################
     467                 :             : !### 09. Compute the next values
     468                 :             : 
     469   [ -  +  -  - ]:           1 :  if(ionmov==10 .or. itime==1)then
     470                 :             : 
     471                 :             : !  Previous cartesian coordinates
     472         [ +  + ]:           4 :    vin_prev(:)=vin(:)
     473                 :             : 
     474                 :             : !  New atomic cartesian coordinates are obtained from vin, hessin
     475                 :             : !  and vout
     476   [ +  -  +  -  :          40 :    vin = vin - matmul(hessin, vout)
          +  -  -  +  -  
          +  +  +  +  +  
          +  +  +  -  +  
          -  +  -  -  +  
             +  +  +  - ]
     477                 :             : !  Previous atomic forces
     478         [ +  + ]:           4 :    vout_prev(:)=vout(:)
     479                 :             : 
     480                 :             :  else
     481         [ #  # ]:           0 :    if(ionmov==11)then
     482                 :           0 :      ihist_prev = abihist_findIndex(hist,-1)
     483                 :           0 :      etotal_prev=hist%etot(ihist_prev)
     484                 :             : !    Here the BFGS algorithm, modified to take into account the
     485                 :             : !    energy
     486                 :             :      call brdene(etotal,etotal_prev,hessin,&
     487                 :           0 : &     ndim,vin,vin_prev,vout,vout_prev)
     488                 :             : 
     489                 :             :    end if
     490                 :             : 
     491                 :             : !  DEBUG (vin,vout and hessin after prediction)
     492         [ #  # ]:           0 :    if(DEBUG)then
     493                 :           0 :      write(std_out,*) 'Vectors vin and vout [after prediction]'
     494                 :           0 :      write(std_out,*) 'vin:'
     495   [ #  #  #  # ]:           0 :      do ii=1,ndim,3
     496         [ #  # ]:           0 :        if (ii+2<=ndim)then
     497                 :           0 :          write(std_out,*) ii,vin(ii:ii+2)
     498                 :             :        else
     499                 :           0 :          write(std_out,*) ii,vin(ii:ndim)
     500                 :             :        end if
     501                 :             :      end do
     502                 :           0 :      write(std_out,*) 'vout:'
     503   [ #  #  #  # ]:           0 :      do ii=1,ndim,3
     504         [ #  # ]:           0 :        if (ii+2<=ndim)then
     505                 :           0 :          write(std_out,*) ii,vout(ii:ii+2)
     506                 :             :        else
     507                 :           0 :          write(std_out,*) ii,vout(ii:ndim)
     508                 :             :        end if
     509                 :             :      end do
     510                 :             :    end if
     511                 :             : 
     512                 :             : !  Implement fixing of atoms : put back old values for fixed
     513                 :             : !  components
     514         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     515         [ #  # ]:           0 :      do jj=1,3
     516                 :             : !      Warning : implemented in reduced coordinates
     517         [ #  # ]:           0 :        if ( ab_mover%iatfix(jj,kk)==1) then
     518                 :           0 :          vin(jj+(kk-1)*3)=vin_prev(jj+(kk-1)*3)
     519                 :             :        end if
     520                 :             :      end do
     521                 :             :    end do
     522                 :             :  end if
     523                 :             : 
     524                 :             : !write(std_out,*) 'delocint 10'
     525                 :             : !##########################################################
     526                 :             : !### 10. Convert from delocalized to xcart and xred
     527                 :             : 
     528                 :             : !Transfer vin  to deloc_int, acell and rprimd
     529                 :             :  call xfpack_vin2x(acell, acell0, ab_mover%natom-1, ndim,&
     530                 :             : & ab_mover%nsym, ab_mover%optcell, rprimd, rprimd0,&
     531                 :             : & ab_mover%symrel, ucvol, ucvol0,&
     532   [ +  -  -  -  :           1 : & vin, deloc_int)
          -  -  -  -  -  
                -  -  + ]
     533                 :             : 
     534         [ +  - ]:           1 :  if(DEBUG)then
     535                 :           1 :    write (std_out,*) 'Delocalized internals (deloc_int) [after prediction]:'
     536                 :           1 :    write(std_out,*) 'deloc_int:'
     537   [ -  +  -  + ]:           2 :    do ii=1,ndeloc,3
     538         [ +  - ]:           2 :      if (ii+2<=ndeloc)then
     539                 :           1 :        write(std_out,*) ii,deloc_int(ii:ii+2)
     540                 :             :      else
     541                 :           0 :        write(std_out,*) ii,deloc_int(ii:ndeloc)
     542                 :             :      end if
     543                 :             :    end do
     544                 :           1 :    write(std_out,*) 'BT Inverse Matrix:'
     545         [ +  + ]:           7 :    do ii=1,3*ab_mover%natom
     546                 :           7 :      write(std_out,*) bt_inv_matrix(:,ii)
     547                 :             :    end do
     548                 :           1 :    write (std_out,*) 'xcart (before deloc2xcart):'
     549         [ +  + ]:           3 :    do ii=1,ab_mover%natom
     550                 :           3 :      write (std_out,*) xcart(:,ii)
     551                 :             :    end do
     552                 :             :  end if
     553                 :             : 
     554                 :             : !this routine contains an iterative scheme to find xcart
     555                 :             : !from the non-linear relations between deloc and xcart
     556                 :             : !SIGNIFICANTLY DIFFERENT FROM xcart2deloc
     557                 :             :  call deloc2xcart(deloc,ab_mover%natom,rprimd,xcart,&
     558                 :           1 : & deloc_int,bt_inv_matrix,u_matrix)
     559                 :             : 
     560                 :             : !Convert new xcart (cartesian) to xred (reduced coordinates)
     561                 :           1 :  call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
     562                 :             : 
     563                 :             : 
     564                 :             : !write(std_out,*) 'delocint 11'
     565                 :             : !##########################################################
     566                 :             : !### 11. Update the history with the prediction
     567                 :             : 
     568                 :             : !Increase indexes
     569                 :           1 :  hist%ihist = abihist_findIndex(hist,+1)
     570                 :             : 
     571         [ -  + ]:           1 :  if(ab_mover%optcell/=0)then
     572                 :           0 :    call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     573                 :             :  end if
     574                 :             : 
     575                 :             : !Fill the history with the variables
     576                 :             : !xred, acell, rprimd, vel
     577                 :           1 :  call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     578                 :           1 :  ihist_prev = abihist_findIndex(hist,-1)
     579   [ +  +  +  + ]:           9 :  hist%vel(:,:,hist%ihist)=hist%vel(:,:,ihist_prev)
     580                 :             : 
     581         [ -  + ]:           1 :  if(zDEBUG)then
     582                 :           0 :    write (std_out,*) 'residual:'
     583         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     584                 :           0 :      write (std_out,*) residual(:,kk)
     585                 :             :    end do
     586                 :           0 :    write (std_out,*) 'strten:'
     587                 :           0 :    write (std_out,*) strten(1:3),ch10,strten(4:6)
     588                 :           0 :    write (std_out,*) 'etotal:'
     589                 :           0 :    write (std_out,*) etotal
     590                 :             :  end if
     591                 :             : 
     592                 :             : end subroutine pred_delocint
     593                 :             : !!***
     594                 :             : 
     595                 :             : !!****f* ABINIT/deloc2xcart
     596                 :             : !! NAME
     597                 :             : !! deloc2xcart
     598                 :             : !!
     599                 :             : !! FUNCTION
     600                 :             : !!  Determine the cartesian coordinates which correspond to the
     601                 :             : !!  given values of the delocalized coordinates. The relationship
     602                 :             : !!  is non-linear, so use an iterative scheme, as in Baker
     603                 :             : !!  JCP .105. 192 (1996).
     604                 :             : !!  Older reference: Pulay and co. JACS 101 2550 (1979)
     605                 :             : !!
     606                 :             : !! INPUTS
     607                 :             : !!   deloc <type(delocint)>=Important variables for
     608                 :             : !!   |                           pred_delocint
     609                 :             : !!   |
     610                 :             : !!   | nang     = Number of angles
     611                 :             : !!   | nbond    = Number of bonds
     612                 :             : !!   | ncart    = Number of cartesian directions
     613                 :             : !!   |             (used for constraints)
     614                 :             : !!   | ndihed   = Number of dihedrals
     615                 :             : !!   | nrshift  = Dimension of rshift
     616                 :             : !!   | ninternal= Number of internal coordinates
     617                 :             : !!   |            ninternal=nbond+nang+ndihed+ncart
     618                 :             : !!   |
     619                 :             : !!   | angs(2,3,nang)  = Indexes to characterize angles
     620                 :             : !!   | bonds(2,2,nbond)= For a bond between iatom and jatom
     621                 :             : !!   |                   bonds(1,1,nbond) = iatom
     622                 :             : !!   |                   bonds(2,1,nbond) = icenter
     623                 :             : !!   |                   bonds(1,2,nbond) = jatom
     624                 :             : !!   |                   bonds(2,2,nbond) = irshift
     625                 :             : !!   | carts(2,ncart)  = Index of total primitive internal,
     626                 :             : !!   |                   and atom (carts(2,:))
     627                 :             : !!   | dihedrals(2,4,ndihed)= Indexes to characterize dihedrals
     628                 :             : !!   |
     629                 :             : !!   | rshift(3,nrshift)= Shift in xred that must be done to find
     630                 :             : !!   |                    all neighbors of a given atom within a
     631                 :             : !!   |                    given number of neighboring shells
     632                 :             : !! natom = Number of atoms (dtset%natom)
     633                 :             : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
     634                 :             : !!
     635                 :             : !! OUTPUT
     636                 :             : !! bt_inv_matrix(3*(natom-1),3*natom)=inverse of transpose of B matrix
     637                 :             : !!
     638                 :             : !! SIDE EFFECTS
     639                 :             : !! u_matrix(ninternal,3*(natom-1))=eigenvectors of G = BB^T matrix
     640                 :             : !! xcart(3,natom)=cartesian coordinates of atoms (bohr)
     641                 :             : !!
     642                 :             : !! NOTES
     643                 :             : !!
     644                 :             : !! SOURCE
     645                 :             : 
     646                 :           1 : subroutine deloc2xcart(deloc,natom,rprimd,xcart,deloc_int,btinv,u_matrix)
     647                 :             : 
     648                 :             : !Arguments ------------------------------------
     649                 :             : !scalars
     650                 :             :  integer,intent(in) :: natom
     651                 :             :  type(delocint),intent(in) :: deloc
     652                 :             : !arrays
     653                 :             :  real(dp),intent(in) :: deloc_int(3*(natom-1)),rprimd(3,3)
     654                 :             :  real(dp),intent(inout) :: u_matrix(deloc%ninternal,3*(natom-1))
     655                 :             :  real(dp),intent(inout) :: xcart(3,natom)
     656                 :             :  real(dp),intent(out) :: btinv(3*(natom-1),3*natom)
     657                 :             : 
     658                 :             : !Local variables-------------------------------
     659                 :             : !scalars
     660                 :             :  integer :: iiter,iprim,niter
     661                 :             :  integer :: ii
     662                 :             :  real(dp) :: minmix, maxmix
     663                 :             :  real(dp) :: mix,tot_diff, toldeloc
     664                 :             :  real(dp) :: lntoldeloc
     665                 :             :  logical  :: DEBUG=.FALSE.
     666                 :             : !arrays
     667                 :           2 :  real(dp) :: btinv_tmp(3*(natom-1),3*natom)
     668                 :           2 :  real(dp) :: cgrad(3*natom),cgrad_old(3*natom)
     669                 :           2 :  real(dp) :: deloc_int_now(3*(natom-1)),prim_int(deloc%ninternal)
     670                 :           2 :  real(dp) :: tmpxcart(3*natom)
     671                 :           2 :  real(dp) :: xdeloc_diff(3*(natom-1))
     672                 :             : 
     673                 :             :  character(len=500) :: message
     674                 :             : 
     675                 :             : ! ******************************************************************
     676                 :             : 
     677         [ -  + ]:           1 :  if (DEBUG) then
     678                 :           0 :    write(ab_out,*) 'ENTERING DELOC2XCART'
     679                 :             : 
     680                 :           0 :    write (message,*) 'BONDS=',deloc%nbond
     681                 :           0 :    call wrtout(ab_out,message,'COLL')
     682         [ #  # ]:           0 :    do ii = 1, deloc%nbond
     683                 :           0 :      write (message,*) ii, deloc%bonds(:,:,ii)
     684                 :           0 :      call wrtout(ab_out,message,'COLL')
     685                 :             :    end do
     686                 :             : 
     687                 :           0 :    write (message,*) 'ANGS=',deloc%nang
     688                 :           0 :    call wrtout(ab_out,message,'COLL')
     689         [ #  # ]:           0 :    do ii = 1, deloc%nang
     690                 :           0 :      write (message,*) ii, deloc%angs(:,:,ii)
     691                 :           0 :      call wrtout(ab_out,message,'COLL')
     692                 :             :    end do
     693                 :             : 
     694                 :           0 :    write (message,*) 'DIHEDRALS=',deloc%ndihed
     695                 :           0 :    call wrtout(ab_out,message,'COLL')
     696         [ #  # ]:           0 :    do ii = 1, deloc%ndihed
     697                 :           0 :      write (message,*) ii, deloc%dihedrals(:,:,ii)
     698                 :           0 :      call wrtout(ab_out,message,'COLL')
     699                 :             :    end do
     700                 :             : 
     701                 :           0 :    write (message,*) 'CARTS=',deloc%ncart
     702                 :           0 :    call wrtout(ab_out,message,'COLL')
     703         [ #  # ]:           0 :    do ii = 1, deloc%ncart
     704                 :           0 :      write (message,*) ii, deloc%carts(:,ii)
     705                 :           0 :      call wrtout(ab_out,message,'COLL')
     706                 :             :    end do
     707                 :             : 
     708                 :           0 :    write (ab_out,*) 'xcart (input)'
     709         [ #  # ]:           0 :    do ii=1,natom
     710                 :           0 :      write (ab_out,*) xcart(:,ii)
     711                 :             :    end do
     712                 :             : 
     713                 :             :  end if
     714                 :             : 
     715                 :           1 :  niter = 200
     716         [ +  + ]:           2 :  tmpxcart = reshape(xcart,(/3*natom/))
     717                 :             : 
     718         [ +  + ]:           7 :  cgrad_old(:) = zero
     719         [ +  + ]:           7 :  cgrad(:) = zero
     720                 :             :  maxmix = 0.9_dp
     721                 :             :  minmix = 0.2_dp
     722                 :             :  toldeloc = tol10
     723                 :             :  lntoldeloc = log(toldeloc)
     724                 :             : 
     725         [ +  - ]:          62 :  do iiter=1,niter
     726         [ +  + ]:          62 :    if (iiter==1) then
     727                 :             :      mix= minmix
     728                 :             :    else
     729                 :          61 :      mix = minmix + (maxmix-minmix)*(log(tot_diff)-lntoldeloc) / lntoldeloc
     730                 :             :    end if
     731         [ -  + ]:          61 :    if (mix < minmix) mix = minmix
     732                 :             :    if (mix > maxmix) mix = maxmix
     733                 :             : 
     734         [ +  + ]:         434 :    tmpxcart(:) = tmpxcart(:) + mix*cgrad(:)
     735         [ +  + ]:         186 :    xcart = reshape(tmpxcart,(/3,natom/))
     736                 :             :    call xcart2deloc(deloc,natom,rprimd,xcart,&
     737                 :          62 : &   btinv_tmp,u_matrix,deloc_int_now,prim_int)
     738                 :             : !  update the BT^{-1} matrix?
     739   [ +  +  +  + ]:        1550 :    btinv(:,:) = btinv_tmp(:,:)
     740                 :             : 
     741         [ +  + ]:         248 :    xdeloc_diff(:) = deloc_int(:) - deloc_int_now(:)
     742                 :             : 
     743         [ +  + ]:         248 :    tot_diff = sum(abs(xdeloc_diff))
     744         [ +  + ]:          62 :    if (tot_diff < toldeloc) exit
     745                 :             : 
     746         [ +  + ]:         427 :    cgrad_old(:) = cgrad(:)
     747                 :             : 
     748                 :             : !  gradient vector = btinv^{T} * xdeloc_diff
     749                 :             :    call dgemv('T',3*(natom-1),3*natom,one,&
     750                 :          62 : &   btinv,3*(natom-1),xdeloc_diff,1,zero,cgrad,1)
     751                 :             :  end do
     752                 :             : !end iiter do
     753                 :             : 
     754                 :             :  call xcart2deloc(deloc,natom,rprimd,xcart,&
     755                 :           1 : & btinv,u_matrix,deloc_int_now,prim_int)
     756                 :           1 :  write (message,'(3a)') 'delocalized internals, after convergence of xcart = ', ch10
     757                 :           1 :  call wrtout(std_out,message,'COLL')
     758         [ +  + ]:           4 :  do ii = 1, 3*(natom-1)
     759                 :           3 :    write (message,'(I6,E20.10,2x)') ii, deloc_int_now(ii)
     760                 :           4 :    call wrtout(std_out,message,'COLL')
     761                 :             :  end do
     762                 :             : 
     763         [ +  + ]:           4 :  xdeloc_diff(:) = deloc_int(:) - deloc_int_now(:)
     764                 :             : 
     765                 :           1 :  write (message,'(a)') 'Primitive internal coordinate values:'
     766                 :           1 :  call wrtout(std_out,message,'COLL')
     767         [ +  + ]:           5 :  do iprim = 1, deloc%nbond
     768                 :           4 :    write (message,'(i6,E20.10)') iprim, prim_int(iprim)
     769                 :           5 :    call wrtout(std_out,message,'COLL')
     770                 :             :  end do
     771         [ +  + ]:          49 :  do iprim = deloc%nbond+1, deloc%nbond+deloc%nang+deloc%ndihed
     772                 :          48 :    write (message,'(i6,2E20.10)') iprim, prim_int(iprim), prim_int(iprim)/pi*180.0_dp
     773                 :          49 :    call wrtout(std_out,message,'COLL')
     774                 :             :  end do
     775         [ -  + ]:           1 :  do iprim = deloc%nbond+deloc%nang+deloc%ndihed+1, deloc%ninternal
     776                 :           0 :    write (message,'(i6,E20.10)') iprim, prim_int(iprim)
     777                 :           1 :    call wrtout(std_out,message,'COLL')
     778                 :             :  end do
     779                 :             : 
     780         [ -  + ]:           1 :  if (iiter == niter+1) then
     781                 :           0 :    write (message,'(a,i6,a,E20.10)') 'deloc2xcart : Error, xcart not converged in ', niter, 'iterations ', tot_diff
     782                 :           0 :    ABI_ERROR(message)
     783                 :             :  end if
     784                 :             : 
     785         [ -  + ]:           1 :  if(DEBUG)then
     786                 :           0 :    write (ab_out,*) 'xcart (output)'
     787         [ #  # ]:           0 :    do ii=1,natom
     788                 :           0 :      write (ab_out,*) xcart(:,ii)
     789                 :             :    end do
     790                 :           0 :    write(ab_out,*) 'EXITING DELOC2XCART'
     791                 :             :  end if
     792                 :             : 
     793                 :           1 : end subroutine deloc2xcart
     794                 :             : !!***
     795                 :             : 
     796                 :             : !!****f* ABINIT/gred2gdeloc
     797                 :             : !! NAME
     798                 :             : !! gred2gdeloc
     799                 :             : !!
     800                 :             : !! FUNCTION
     801                 :             : !!  calculate delocalized forces from reduced coordinate ones
     802                 :             : !!
     803                 :             : !! INPUTS
     804                 :             : !! btinv(3*(natom-1),3*natom)= inverse transpose of B matrix (see delocint)
     805                 :             : !! natom = number of atoms
     806                 :             : !! gprimd(3,3)=dimensional translations in reciprocal space (bohr-1)
     807                 :             : !!
     808                 :             : !! OUTPUT
     809                 :             : !! deloc_gred(3*(natom-1))=delocalized gradients from reduced coordinate ones
     810                 :             : !! gred(3,natom)=delocalized gradients in reduced coordinates
     811                 :             : !!
     812                 :             : !! SOURCE
     813                 :             : 
     814                 :           1 : subroutine gred2gdeloc(btinv,deloc_gred,gred,natom,gprimd)
     815                 :             : 
     816                 :             : !Arguments ------------------------------------
     817                 :             : !scalars
     818                 :             :  integer, intent(in) :: natom
     819                 :             : !arrays
     820                 :             :  real(dp),intent(in) :: btinv(3*(natom-1),3*natom),gprimd(3,3),gred(3,natom)
     821                 :             :  real(dp),intent(out) :: deloc_gred(3*(natom-1))
     822                 :             : 
     823                 :             : !Local variables-------------------------------
     824                 :             :  integer :: ii
     825                 :             : !arrays
     826                 :           2 :  real(dp) :: fcart(3,natom)
     827                 :             :  character(len=500) :: message
     828                 :             : 
     829                 :             : ! ******************************************************************
     830                 :             : 
     831                 :             : !make cartesian forces
     832                 :             : 
     833                 :             :  call dgemm('N','N',3,natom,3,one,&
     834                 :           1 : & gprimd,3,gred,3,zero,fcart,3)
     835                 :             : 
     836                 :             : !turn cartesian to delocalized forces
     837                 :             :  call dgemv('N',3*(natom-1),3*natom,one,&
     838                 :           1 : & btinv,3*(natom-1),fcart,1,zero,deloc_gred,1)
     839                 :             : 
     840                 :           1 :  write (message,'(a)') 'gred2gdeloc : deloc_gred = '
     841                 :           1 :  call wrtout(std_out,message,'COLL')
     842                 :             : 
     843         [ +  + ]:           4 :  do ii = 1, 3*(natom-1)
     844                 :           3 :    write (message,'(I6,E16.6)') ii, deloc_gred(ii)
     845                 :           4 :    call wrtout(std_out,message,'COLL')
     846                 :             :  end do
     847                 :             : 
     848                 :           1 : end subroutine gred2gdeloc
     849                 :             : !!***
     850                 :             : 
     851                 :             : !!****f* ABINIT/calc_b_matrix
     852                 :             : !! NAME
     853                 :             : !! calc_b_matrix
     854                 :             : !!
     855                 :             : !! FUNCTION
     856                 :             : !!  calculate values of derivatives of internal coordinates as a function of
     857                 :             : !!  cartesian ones =  B matrix
     858                 :             : !!
     859                 :             : !! INPUTS
     860                 :             : !! angs= number of angles
     861                 :             : !! bonds(2,2,nbond)=for a bond between iatom and jatom
     862                 :             : !!              bonds(1,1,nbond) = iatom
     863                 :             : !!              bonds(2,1,nbond) = icenter
     864                 :             : !!              bonds(1,2,nbond) = jatom
     865                 :             : !!              bonds(2,2,nbond) = irshift
     866                 :             : !! carts(2,ncart)= index of total primitive internal, and atom (carts(2,:))
     867                 :             : !! dihedrals(2,4,ndihed)=indexes to characterize dihedrals
     868                 :             : !! nang(2,3,nang)=indexes to characterize angles
     869                 :             : !! nbond=number of bonds
     870                 :             : !! ncart=number of auxiliary cartesian atom coordinates (used for constraints)
     871                 :             : !! ndihed= number of dihedrals
     872                 :             : !! ninternal=nbond+nang+ndihed+ncart: number of internal coordinates
     873                 :             : !! nrshift= dimension of rshift
     874                 :             : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
     875                 :             : !! rshift(3,nrshift)=shift in xred that must be done to find all neighbors of
     876                 :             : !!                   a given atom within a given number of neighboring shells
     877                 :             : !! xcart(3,natom)=cartesian coordinates of atoms (bohr)
     878                 :             : !!
     879                 :             : !! OUTPUT
     880                 :             : !! b_matrix(ninternal,3*natom)=matrix of derivatives of internal coordinates
     881                 :             : !!   wrt cartesians
     882                 :             : !!
     883                 :             : !! SOURCE
     884                 :             : 
     885                 :          64 : subroutine calc_b_matrix(deloc,natom,rprimd,xcart,b_matrix)
     886                 :             : 
     887                 :             : !Arguments ------------------------------------
     888                 :             : !scalars
     889                 :             :  integer,intent(in) :: natom
     890                 :             :  type(delocint),intent(in) :: deloc
     891                 :             : 
     892                 :             : !arrays
     893                 :             :  real(dp),intent(in) :: rprimd(3,3),xcart(3,natom)
     894                 :             :  real(dp),intent(out) :: b_matrix(deloc%ninternal,3*natom)
     895                 :             : 
     896                 :             : !Local variables-------------------------------
     897                 :             : !scalars
     898                 :             :  integer :: i1,i2,i3,i4,iang,ibond,icart,idihed,iprim,s1,s2,s3,s4
     899                 :             : !arrays
     900                 :             :  real(dp) :: bb(3),r1(3),r2(3),r3(3),r4(3)
     901                 :             : 
     902                 :             : ! *************************************************************************
     903                 :             : 
     904                 :          64 :  iprim=0
     905   [ +  +  +  + ]:       20416 :  b_matrix(:,:) = zero
     906                 :             : 
     907         [ +  + ]:         320 :  do ibond=1,deloc%nbond
     908                 :         256 :    i1 = deloc%bonds(1,1,ibond)
     909                 :         256 :    s1 = deloc%bonds(2,1,ibond)
     910                 :             :    r1(:) = xcart(:,i1)+deloc%rshift(1,s1)*rprimd(:,1)&
     911                 :             : &   +deloc%rshift(2,s1)*rprimd(:,2)&
     912         [ +  + ]:        1024 : &   +deloc%rshift(3,s1)*rprimd(:,3)
     913                 :         256 :    i2 = deloc%bonds(1,2,ibond)
     914                 :         256 :    s2 = deloc%bonds(2,2,ibond)
     915                 :             :    r2(:) = xcart(:,i2)+deloc%rshift(1,s2)*rprimd(:,1)&
     916                 :             : &   +deloc%rshift(2,s2)*rprimd(:,2)&
     917         [ +  + ]:        1024 : &   +deloc%rshift(3,s2)*rprimd(:,3)
     918                 :         256 :    iprim=iprim+1
     919                 :         256 :    call dbond_length_d1(r1,r2,bb)
     920         [ +  + ]:        1024 :    b_matrix(iprim,3*(i1-1)+1:3*i1) = b_matrix(iprim,3*(i1-1)+1:3*i1) + bb(:)
     921                 :         256 :    call dbond_length_d1(r2,r1,bb)
     922         [ +  + ]:        1088 :    b_matrix(iprim,3*(i2-1)+1:3*i2) = b_matrix(iprim,3*(i2-1)+1:3*i2) + bb(:)
     923                 :             :  end do
     924                 :             : 
     925                 :             : !second: angle values (ang)
     926         [ +  + ]:         832 :  do iang=1,deloc%nang
     927                 :         768 :    i1 = deloc%angs(1,1,iang)
     928                 :         768 :    s1 = deloc%angs(2,1,iang)
     929                 :             :    r1(:) = xcart(:,i1)+deloc%rshift(1,s1)*rprimd(:,1)&
     930                 :             : &   +deloc%rshift(2,s1)*rprimd(:,2)&
     931         [ +  + ]:        3072 : &   +deloc%rshift(3,s1)*rprimd(:,3)
     932                 :         768 :    i2 = deloc%angs(1,2,iang)
     933                 :         768 :    s2 = deloc%angs(2,2,iang)
     934                 :             :    r2(:) = xcart(:,i2)+deloc%rshift(1,s2)*rprimd(:,1)&
     935                 :             : &   +deloc%rshift(2,s2)*rprimd(:,2)&
     936         [ +  + ]:        3072 : &   +deloc%rshift(3,s2)*rprimd(:,3)
     937                 :         768 :    i3 = deloc%angs(1,3,iang)
     938                 :         768 :    s3 = deloc%angs(2,3,iang)
     939                 :             :    r3(:) = xcart(:,i3)+deloc%rshift(1,s3)*rprimd(:,1)&
     940                 :             : &   +deloc%rshift(2,s3)*rprimd(:,2)&
     941         [ +  + ]:        3072 : &   +deloc%rshift(3,s3)*rprimd(:,3)
     942                 :         768 :    iprim=iprim+1
     943                 :         768 :    call dang_d1(r1,r2,r3,bb)
     944         [ +  + ]:        3072 :    b_matrix(iprim,3*(i1-1)+1:3*i1) = b_matrix(iprim,3*(i1-1)+1:3*i1) + bb(:)
     945                 :         768 :    call dang_d2(r1,r2,r3,bb)
     946         [ +  + ]:        3072 :    b_matrix(iprim,3*(i2-1)+1:3*i2) = b_matrix(iprim,3*(i2-1)+1:3*i2) + bb(:)
     947                 :         768 :    call dang_d1(r3,r2,r1,bb)
     948         [ +  + ]:        3136 :    b_matrix(iprim,3*(i3-1)+1:3*i3) = b_matrix(iprim,3*(i3-1)+1:3*i3) + bb(:)
     949                 :             :  end do
     950                 :             : 
     951                 :             : !third: dihedral values
     952         [ +  + ]:        2368 :  do idihed=1,deloc%ndihed
     953                 :        2304 :    i1 = deloc%dihedrals(1,1,idihed)
     954                 :        2304 :    s1 = deloc%dihedrals(2,1,idihed)
     955                 :             :    r1(:) = xcart(:,i1)+deloc%rshift(1,s1)*rprimd(:,1)&
     956                 :             : &   +deloc%rshift(2,s1)*rprimd(:,2)&
     957         [ +  + ]:        9216 : &   +deloc%rshift(3,s1)*rprimd(:,3)
     958                 :        2304 :    i2 = deloc%dihedrals(1,2,idihed)
     959                 :        2304 :    s2 = deloc%dihedrals(2,2,idihed)
     960                 :             :    r2(:) = xcart(:,i2)+deloc%rshift(1,s2)*rprimd(:,1)&
     961                 :             : &   +deloc%rshift(2,s2)*rprimd(:,2)&
     962         [ +  + ]:        9216 : &   +deloc%rshift(3,s2)*rprimd(:,3)
     963                 :        2304 :    i3 = deloc%dihedrals(1,3,idihed)
     964                 :        2304 :    s3 = deloc%dihedrals(2,3,idihed)
     965                 :             :    r3(:) = xcart(:,i3)+deloc%rshift(1,s3)*rprimd(:,1)&
     966                 :             : &   +deloc%rshift(2,s3)*rprimd(:,2)&
     967         [ +  + ]:        9216 : &   +deloc%rshift(3,s3)*rprimd(:,3)
     968                 :        2304 :    i4 = deloc%dihedrals(1,4,idihed)
     969                 :        2304 :    s4 = deloc%dihedrals(2,4,idihed)
     970                 :             :    r4(:) = xcart(:,i4)+deloc%rshift(1,s4)*rprimd(:,1)&
     971                 :             : &   +deloc%rshift(2,s4)*rprimd(:,2)&
     972         [ +  + ]:        9216 : &   +deloc%rshift(3,s4)*rprimd(:,3)
     973                 :             : !  write(std_out,*) 'dihed ',idihed
     974                 :             : !  write(std_out,*) r1
     975                 :             : !  write(std_out,*) r2
     976                 :             : !  write(std_out,*) r3
     977                 :             : !  write(std_out,*) r4
     978                 :             : 
     979                 :        2304 :    iprim=iprim+1
     980                 :        2304 :    call ddihedral_d1(r1,r2,r3,r4,bb)
     981         [ +  + ]:        9216 :    b_matrix(iprim,3*(i1-1)+1:3*i1) = b_matrix(iprim,3*(i1-1)+1:3*i1) + bb(:)
     982                 :        2304 :    call ddihedral_d2(r1,r2,r3,r4,bb)
     983         [ +  + ]:        9216 :    b_matrix(iprim,3*(i2-1)+1:3*i2) = b_matrix(iprim,3*(i2-1)+1:3*i2) + bb(:)
     984                 :        2304 :    call ddihedral_d2(r4,r3,r2,r1,bb)
     985         [ +  + ]:        9216 :    b_matrix(iprim,3*(i3-1)+1:3*i3) = b_matrix(iprim,3*(i3-1)+1:3*i3) + bb(:)
     986                 :        2304 :    call ddihedral_d1(r4,r3,r2,r1,bb)
     987         [ +  + ]:        9280 :    b_matrix(iprim,3*(i4-1)+1:3*i4) = b_matrix(iprim,3*(i4-1)+1:3*i4) + bb(:)
     988                 :             :  end do
     989                 :             : 
     990         [ -  + ]:          64 :  do icart=1,deloc%ncart
     991                 :           0 :    iprim=iprim+1
     992                 :             :    b_matrix(iprim,3*(deloc%carts(2,icart)-1)+deloc%carts(1,icart)) = &
     993                 :          64 : &   b_matrix(iprim,3*(deloc%carts(2,icart)-1)+deloc%carts(1,icart)) + one
     994                 :             :  end do
     995                 :             : 
     996                 :             : !DEBUG
     997                 :             : ! write (200,*) 'calc_b_matrix : b_matrix = '
     998                 :             : ! do iprim=1,deloc%ninternal
     999                 :             : !   do i1=1, 3*natom
    1000                 :             : !     write (200,'(E16.6,2x)',ADVANCE='NO') b_matrix(iprim,i1)
    1001                 :             : !   end do
    1002                 :             : !   write (200,*)
    1003                 :             : ! end do
    1004                 :             : !ENDDEBUG
    1005                 :             : 
    1006                 :          64 : end subroutine calc_b_matrix
    1007                 :             : !!***
    1008                 :             : 
    1009                 :             : !!****f* ABINIT/dbond_length_d1
    1010                 :             : !! NAME
    1011                 :             : !! dbond_length_d1
    1012                 :             : !!
    1013                 :             : !! FUNCTION
    1014                 :             : !!
    1015                 :             : !! SOURCE
    1016                 :             : !!
    1017                 :             : 
    1018                 :         512 : subroutine dbond_length_d1(r1,r2,bb)
    1019                 :             : 
    1020                 :             : !Arguments ------------------------------------
    1021                 :             : !arrays
    1022                 :             :  real(dp),intent(in) :: r1(3),r2(3)
    1023                 :             :  real(dp),intent(out) :: bb(3)
    1024                 :             : 
    1025                 :             : !Local variables ------------------------------
    1026                 :             : !arrays
    1027                 :             :  real(dp) :: rpt(3)
    1028                 :             : 
    1029                 :             : !************************************************************************
    1030         [ +  + ]:        2048 :  rpt(:) = r1(:)-r2(:)
    1031         [ +  + ]:        2048 :  bb(:) = rpt(:)/bond_length(r1,r2)
    1032                 :             : 
    1033                 :         512 : end subroutine dbond_length_d1
    1034                 :             : !!***
    1035                 :             : 
    1036                 :             : 
    1037                 :             : !!****f* ABINIT/dang_d1
    1038                 :             : !! NAME
    1039                 :             : !! dang_d1
    1040                 :             : !!
    1041                 :             : !! FUNCTION
    1042                 :             : !!
    1043                 :             : !! SOURCE
    1044                 :             : !!
    1045                 :             : 
    1046                 :        1536 : subroutine dang_d1(r1,r2,r3,bb)
    1047                 :             : 
    1048                 :             : !Arguments ------------------------------------
    1049                 :             : !arrays
    1050                 :             :  real(dp),intent(in) :: r1(3),r2(3),r3(3)
    1051                 :             :  real(dp),intent(out) :: bb(3)
    1052                 :             : 
    1053                 :             : !Local variables ------------------------------
    1054                 :             : !scalars
    1055                 :             :  real(dp) :: cos_ang,n1,n1232,n2,tmp
    1056                 :             : !arrays
    1057                 :             :  real(dp) :: cp1232(3),rpt(3),rpt12(3),rpt32(3)
    1058                 :             : 
    1059                 :             : !************************************************************************
    1060                 :        1536 :  n1=bond_length(r1,r2)
    1061                 :        1536 :  n2=bond_length(r3,r2)
    1062                 :             : 
    1063         [ +  + ]:        6144 :  rpt12(:) = r1(:)-r2(:)
    1064         [ +  + ]:        6144 :  rpt32(:) = r3(:)-r2(:)
    1065                 :             : 
    1066         [ +  + ]:        6144 :  cos_ang = dot_product(rpt12,rpt32)/n1/n2
    1067         [ +  - ]:        1536 :  if (cos_ang > one - epsilon(one)*two) then
    1068                 :             :    cos_ang = one
    1069         [ -  + ]:        1536 :  else if(cos_ang < -one + epsilon(one)*two) then
    1070                 :           0 :    cos_ang = -one
    1071                 :             :  end if
    1072                 :             : 
    1073         [ +  + ]:        6144 :  rpt(:) = rpt32(:)/n1/n2 - rpt12(:)*cos_ang/n1/n1
    1074                 :             : 
    1075                 :        1536 :  tmp = sqrt(one-cos_ang**2)
    1076                 :        1536 :  bb(:) = zero
    1077         [ +  - ]:        1536 :  if (tmp > epsilon(one)) then
    1078         [ +  + ]:        6144 :    bb(:) = rpt(:) * (-one)/tmp
    1079                 :             :  end if
    1080                 :             : 
    1081                 :             : !TEST: version from MOLECULAR VIBRATIONS EB Wilson
    1082                 :        1536 :  call acrossb(rpt12,rpt32,cp1232)
    1083   [ +  +  +  -  :        6144 :  n1232 = norm2(cp1232)
                   +  + ]
    1084         [ +  + ]:        6144 :  rpt(:) = (cos_ang*rpt12(:)*n2/n1 - rpt32(:))/n1232
    1085         [ -  + ]:        1536 :  if (abs(bb(1)-rpt(1))+abs(bb(2)-rpt(2))+abs(bb(3)-rpt(3)) > tol10) then
    1086                 :           0 :    write(std_out,*) 'Compare bb ang 1 : '
    1087         [ #  # ]:           0 :    write(std_out,*) bb(:), rpt(:), bb(:)-rpt(:)
    1088                 :             :  end if
    1089                 :        1536 :  bb(:) = rpt(:)
    1090                 :             : 
    1091                 :        1536 : end subroutine dang_d1
    1092                 :             : !!***
    1093                 :             : 
    1094                 :             : 
    1095                 :             : !!****f* ABINIT/dang_d2
    1096                 :             : !! NAME
    1097                 :             : !! dang_d2
    1098                 :             : !!
    1099                 :             : !! FUNCTION
    1100                 :             : !!
    1101                 :             : !! SOURCE
    1102                 :             : !!
    1103                 :             : 
    1104                 :         768 : subroutine dang_d2(r1,r2,r3,bb)
    1105                 :             : 
    1106                 :             : !Arguments ------------------------------------
    1107                 :             : !arrays
    1108                 :             :  real(dp),intent(in) :: r1(3),r2(3),r3(3)
    1109                 :             :  real(dp),intent(out) :: bb(3)
    1110                 :             : 
    1111                 :             : !Local variables ------------------------------
    1112                 :             : !scalars
    1113                 :             :  real(dp) :: cos_ang,n1,n1232,n2,tmp
    1114                 :             : !arrays
    1115                 :             :  real(dp) :: cp1232(3),rpt(3),rpt12(3),rpt32(3)
    1116                 :             : 
    1117                 :             : !************************************************************************
    1118                 :         768 :  n1=bond_length(r1,r2)
    1119                 :         768 :  n2=bond_length(r3,r2)
    1120                 :             : 
    1121         [ +  + ]:        3072 :  rpt12(:) = r1(:)-r2(:)
    1122         [ +  + ]:        3072 :  rpt32(:) = r3(:)-r2(:)
    1123                 :             : 
    1124         [ +  + ]:        3072 :  cos_ang = dot_product(rpt12,rpt32)/n1/n2
    1125         [ +  - ]:         768 :  if (cos_ang > one - epsilon(one)*two) then
    1126                 :             :    cos_ang = one
    1127         [ -  + ]:         768 :  else if(cos_ang < -one + epsilon(one)*two) then
    1128                 :           0 :    cos_ang = -one
    1129                 :             :  end if
    1130                 :             : 
    1131                 :             :  rpt(:) = -rpt32(:)/n1/n2 - rpt12(:)/n1/n2 &
    1132         [ +  + ]:        3072 : & + rpt12(:)*cos_ang/n1/n1 + rpt32(:)*cos_ang/n2/n2
    1133                 :             : 
    1134                 :         768 :  tmp = sqrt(one-cos_ang**2)
    1135                 :         768 :  bb(:) = zero
    1136         [ +  - ]:         768 :  if (tmp > tol12) then
    1137         [ +  + ]:        3072 :    bb(:) = rpt(:) * (-one)/tmp
    1138                 :             :  end if
    1139                 :             : 
    1140                 :             : !TEST: version from MOLECULAR VIBRATIONS EB Wilson
    1141                 :         768 :  call acrossb(rpt12,rpt32,cp1232)
    1142   [ +  +  +  -  :        3072 :  n1232 = norm2(cp1232)
                   +  + ]
    1143         [ +  + ]:        3072 :  rpt(:) = ((n1-n2*cos_ang)*rpt12(:)/n1 + (n2-n1*cos_ang)*rpt32(:)/n2) / n1232
    1144         [ -  + ]:         768 :  if (abs(bb(1)-rpt(1))+abs(bb(2)-rpt(2))+abs(bb(3)-rpt(3))  > tol10) then
    1145                 :           0 :    write(std_out,*) 'Compare bb ang 2 : '
    1146         [ #  # ]:           0 :    write(std_out,*) bb(:), rpt(:), bb(:)-rpt(:)
    1147                 :             :  end if
    1148                 :         768 :  bb(:) = rpt(:)
    1149                 :             : 
    1150                 :         768 : end subroutine dang_d2
    1151                 :             : !!***
    1152                 :             : 
    1153                 :             : !!****f* ABINIT/ddihedral_d1
    1154                 :             : !! NAME
    1155                 :             : !! ddihedral_d1
    1156                 :             : !!
    1157                 :             : !! FUNCTION
    1158                 :             : !!
    1159                 :             : !! SOURCE
    1160                 :             : !!
    1161                 :             : 
    1162                 :        4608 : subroutine ddihedral_d1(r1,r2,r3,r4,bb)
    1163                 :             : 
    1164                 :             : !Arguments ------------------------------------
    1165                 :             : !arrays
    1166                 :             :  real(dp),intent(in) :: r1(3),r2(3),r3(3),r4(3)
    1167                 :             :  real(dp),intent(out) :: bb(3)
    1168                 :             : 
    1169                 :             : !Local variables ------------------------------------
    1170                 :             : !scalars
    1171                 :             :  real(dp) :: cos_dihedral,dih_sign,n1,n2,n23,sin_dihedral,tmp
    1172                 :             : !arrays
    1173                 :             :  real(dp) :: cp1232(3),cp32_1232(3),cp32_3432(3),cp3432(3),cpcp(3),rpt(3)
    1174                 :             :  real(dp) :: rpt12(3),rpt32(3),rpt34(3)
    1175                 :             : 
    1176                 :             : !******************************************************************
    1177         [ +  + ]:       18432 :  rpt12(:) = r1(:)-r2(:)
    1178         [ +  + ]:       18432 :  rpt32(:) = r3(:)-r2(:)
    1179         [ +  + ]:       18432 :  rpt34(:) = r3(:)-r4(:)
    1180                 :             : 
    1181                 :        4608 :  call acrossb(rpt12,rpt32,cp1232)
    1182                 :        4608 :  call acrossb(rpt34,rpt32,cp3432)
    1183                 :             : 
    1184                 :             : !DEBUG
    1185                 :             : !write(std_out,*) ' cos_dihedral : cp1232 = ', cp1232
    1186                 :             : !write(std_out,*) ' cos_dihedral : cp3432 = ', cp3432
    1187                 :             : !ENDDEBUG
    1188                 :             : 
    1189   [ +  +  +  -  :       18432 :  n1 = norm2(cp1232)
                   +  + ]
    1190   [ +  +  +  -  :       18432 :  n2 = norm2(cp3432)
                   +  + ]
    1191                 :             : 
    1192         [ +  + ]:       18432 :  cos_dihedral = dot_product(cp1232,cp3432)/n1/n2
    1193         [ +  + ]:        4608 :  if (cos_dihedral > one - epsilon(one)*two) then
    1194                 :             :    cos_dihedral = one
    1195         [ -  + ]:        3112 :  else if(cos_dihedral < -one + epsilon(one)*two) then
    1196                 :           0 :    cos_dihedral = -one
    1197                 :             :  end if
    1198                 :             : !we use complementary of standard angle, so
    1199                 :             : !cos_dihedral = -cos_dihedral
    1200                 :             : 
    1201                 :        4608 :  call acrossb(cp1232,cp3432,cpcp)
    1202         [ +  + ]:       18432 :  cpcp(:) = cpcp(:)/n1/n2
    1203                 :             : !we use complementary of standard angle, but sin is invariant
    1204   [ +  +  +  +  :       32256 :  sin_dihedral = -dot_product(cpcp,rpt32)/norm2(rpt32)
             +  -  +  + ]
    1205                 :        4608 :  dih_sign = one
    1206         [ +  + ]:        4608 :  if (sin_dihedral < -epsilon(one)) then
    1207                 :        1556 :    dih_sign = -one
    1208                 :             :  end if
    1209                 :             : 
    1210                 :             : !DEBUG
    1211                 :             : !write(std_out,'(a,3E16.6)') 'ddihedral_d1 : cos abs(sin) dih_sign= ',&
    1212                 :             : !&    cos_dihedral,sin_dihedral,dih_sign
    1213                 :             : !ENDDEBUG
    1214                 :             : 
    1215                 :             : !ddihedral_d1 = dih_sign* acos(cos_dihedral)
    1216                 :        4608 :  call acrossb(rpt32,cp1232,cp32_1232)
    1217                 :        4608 :  call acrossb(rpt32,cp3432,cp32_3432)
    1218                 :             : 
    1219         [ +  + ]:       18432 :  rpt(:) = cp32_3432(:)/n1/n2 - cp32_1232(:)/n1/n1 * cos_dihedral
    1220                 :        4608 :  bb(:) = zero
    1221                 :             : 
    1222                 :             : !DEBUG
    1223                 :             : !write(std_out,*) 'ddihedral_d1 cp1232 cp3432 = ',cp1232,cp3432,rpt32
    1224                 :             : !write(std_out,*) 'ddihedral_d1 cp32_1232 cp32_3432 = ',cp32_1232,cp32_3432,cos_dihedral,n1,n2
    1225                 :             : !write(std_out,*) 'ddihedral_d1 rpt = ',rpt
    1226                 :             : !ENDDEBUG
    1227                 :             : 
    1228                 :        4608 :  tmp = sqrt(one-cos_dihedral**2)
    1229         [ +  + ]:        4608 :  if (tmp > tol12) then
    1230                 :             : !  we use complementary of standard angle, so cosine in acos has - sign,
    1231                 :             : !  and it appears for the derivative
    1232         [ +  + ]:       12448 :    bb(:) = -dih_sign * rpt(:) * (-one) / tmp
    1233                 :             :  else
    1234   [ +  +  +  -  :       10472 :    bb(:) = dih_sign * cp32_3432(:) / n1 / n2 / norm2(cp32_3432)
             +  +  +  + ]
    1235                 :             :  end if
    1236                 :             : 
    1237                 :             : !TEST: version from MOLECULAR VIBRATIONS EB Wilson
    1238                 :             : 
    1239   [ +  +  +  -  :       18432 :  n23 = norm2(rpt32)
                   +  + ]
    1240         [ +  + ]:       18432 :  rpt(:) = cp1232(:)*n23/n1/n1
    1241                 :             : !if (abs(bb(1)-rpt(1))+abs(bb(2)-rpt(2))+abs(bb(3)-rpt(3))  > tol10) then
    1242                 :             : !write(std_out,*) 'Compare bb1 : '
    1243                 :             : !write(std_out,*) bb(:), rpt(:), bb(:)-rpt(:)
    1244                 :             : !end if
    1245                 :        4608 :  bb(:) = rpt(:)
    1246                 :             : 
    1247                 :        4608 : end subroutine ddihedral_d1
    1248                 :             : !!***
    1249                 :             : 
    1250                 :             : !!****f* ABINIT/ddihedral_d2
    1251                 :             : !! NAME
    1252                 :             : !! ddihedral_d2
    1253                 :             : !!
    1254                 :             : !! FUNCTION
    1255                 :             : !!
    1256                 :             : !! SOURCE
    1257                 :             : !!
    1258                 :             : 
    1259                 :        4608 : subroutine ddihedral_d2(r1,r2,r3,r4,bb)
    1260                 :             : 
    1261                 :             : !Arguments ------------------------------------
    1262                 :             : !arrays
    1263                 :             :  real(dp),intent(in) :: r1(3),r2(3),r3(3),r4(3)
    1264                 :             :  real(dp),intent(out) :: bb(3)
    1265                 :             : 
    1266                 :             : !Local variables
    1267                 :             : !scalars
    1268                 :             :  real(dp) :: cos_dihedral,dih_sign,n1,n2,n23,sin_dihedral,sp1232,sp3432,tmp
    1269                 :             : !arrays
    1270                 :             :  real(dp) :: cp1232(3),cp1232_12(3),cp1232_34(3),cp32_1232(3),cp32_3432(3)
    1271                 :             :  real(dp) :: cp3432(3),cp3432_12(3),cp3432_34(3),cpcp(3),rpt(3),rpt12(3)
    1272                 :             :  real(dp) :: rpt32(3),rpt34(3)
    1273                 :             : 
    1274                 :             : ! *************************************************************************
    1275         [ +  + ]:       18432 :  rpt12(:) = r1(:)-r2(:)
    1276         [ +  + ]:       18432 :  rpt32(:) = r3(:)-r2(:)
    1277         [ +  + ]:       18432 :  rpt34(:) = r3(:)-r4(:)
    1278                 :             : 
    1279                 :        4608 :  call acrossb(rpt12,rpt32,cp1232)
    1280                 :        4608 :  call acrossb(rpt34,rpt32,cp3432)
    1281                 :             : 
    1282                 :             : !DEBUG
    1283                 :             : !write(std_out,*) ' cos_dihedral : cp1232 = ', cp1232
    1284                 :             : !write(std_out,*) ' cos_dihedral : cp3432 = ', cp3432
    1285                 :             : !ENDDEBUG
    1286                 :             : 
    1287   [ +  +  +  -  :       18432 :  n1 = norm2(cp1232)
                   +  + ]
    1288   [ +  +  +  -  :       18432 :  n2 = norm2(cp3432)
                   +  + ]
    1289                 :             : 
    1290         [ +  + ]:       18432 :  cos_dihedral = dot_product(cp1232,cp3432)/n1/n2
    1291         [ +  + ]:        4608 :  if (cos_dihedral > one - epsilon(one)*two) then
    1292                 :             :    cos_dihedral = one
    1293         [ -  + ]:        3112 :  else if(cos_dihedral < -one + epsilon(one)*two) then
    1294                 :           0 :    cos_dihedral = -one
    1295                 :             :  end if
    1296                 :             : !we use complementary of standard angle, so
    1297                 :             : !cos_dihedral = -cos_dihedral
    1298                 :             : 
    1299                 :        4608 :  call acrossb(cp1232,cp3432,cpcp)
    1300         [ +  + ]:       18432 :  cpcp(:) = cpcp(:)/n1/n2
    1301                 :             : !we use complementary of standard angle, but sin is invariant
    1302   [ +  +  +  +  :       32256 :  sin_dihedral = -dot_product(cpcp,rpt32)/norm2(rpt32)
             +  -  +  + ]
    1303                 :        4608 :  dih_sign = one
    1304         [ +  + ]:        4608 :  if (sin_dihedral <  -tol12) then
    1305                 :        1536 :    dih_sign = -one
    1306                 :             :  end if
    1307                 :             : 
    1308                 :             : !DEBUG
    1309                 :             : !write(std_out,'(a,3E16.6)') 'ddihedral_d2 : cos abs(sin) dih_sign= ',&
    1310                 :             : !&    cos_dihedral,sin_dihedral,dih_sign
    1311                 :             : !ENDDEBUG
    1312                 :             : 
    1313                 :             : !ddihedral_d2 = dih_sign* acos(cos_dihedral)
    1314                 :        4608 :  call acrossb(rpt32,cp3432,cp32_3432)
    1315                 :        4608 :  call acrossb(cp3432,rpt12,cp3432_12)
    1316                 :        4608 :  call acrossb(cp1232,rpt34,cp1232_34)
    1317                 :             : 
    1318                 :        4608 :  call acrossb(rpt32,cp1232,cp32_1232)
    1319                 :        4608 :  call acrossb(cp1232,rpt12,cp1232_12)
    1320                 :        4608 :  call acrossb(cp3432,rpt34,cp3432_34)
    1321                 :             : 
    1322                 :             :  rpt(:) = -(cp32_3432(:) + cp3432_12(:) + cp1232_34(:))/n1/n2 &
    1323         [ +  + ]:       18432 : & +cos_dihedral*(cp32_1232(:)/n1/n1 + cp1232_12(:)/n1/n1 + cp3432_34(:)/n2/n2)
    1324                 :        4608 :  bb(:) = zero
    1325                 :        4608 :  tmp = sqrt(one-cos_dihedral**2)
    1326         [ +  + ]:        4608 :  if (tmp > tol12) then
    1327                 :             : !  we use complementary of standard angle, so cosine in acos has - sign,
    1328                 :             : !  and it appears for derivative
    1329         [ +  + ]:       12448 :    bb(:) = -dih_sign * rpt(:) * (-one) / tmp
    1330                 :             :  else
    1331                 :             :    bb(:) = dih_sign * cos_dihedral * &
    1332                 :             : &   ( cp32_1232(:)/n1/n1/sqrt(cp32_1232(1)**2+cp32_1232(2)**2+cp32_1232(3)**2) &
    1333                 :             : &   +cp1232_12(:)/n1/n1/sqrt(cp1232_12(1)**2+cp1232_12(2)**2+cp1232_12(3)**2) &
    1334         [ +  + ]:        5984 : &   +cp3432_34(:)/n2/n2/sqrt(cp3432_34(1)**2+cp3432_34(2)**2+cp3432_34(3)**2) )
    1335                 :             :  end if
    1336                 :             : 
    1337                 :             : !TEST: version from MOLECULAR VIBRATIONS EB Wilson p. 61
    1338   [ +  +  +  -  :       18432 :  n23 = norm2(rpt32)
                   +  + ]
    1339         [ +  + ]:       18432 :  sp1232 = dot_product(rpt12,rpt32)
    1340         [ +  + ]:       18432 :  sp3432 = dot_product(rpt34,rpt32)
    1341                 :             : 
    1342         [ +  + ]:       18432 :  rpt(:) = -cp1232(:)*(n23-sp1232/n23)/n1/n1 - cp3432(:)*sp3432/n23/n2/n2
    1343                 :             : !if (abs(bb(1)-rpt(1))+abs(bb(2)-rpt(2))+abs(bb(3)-rpt(3))  > tol10) then
    1344                 :             : !write(std_out,*) 'Compare bb2 : '
    1345                 :             : !write(std_out,*) bb(:), rpt(:), bb(:)-rpt(:)
    1346                 :             : !write(std_out,*) -cp1232(:)*(n23-sp1232/n23)/n1/n1, -cp3432(:)*sp3432/n23/n2/n2
    1347                 :             : !end if
    1348                 :        4608 :  bb(:) = rpt(:)
    1349                 :             : 
    1350                 :        4608 : end subroutine ddihedral_d2
    1351                 :             : !!***
    1352                 :             : 
    1353                 :             : !!****f* ABINIT/xcart2deloc
    1354                 :             : !! NAME
    1355                 :             : !! xcart2deloc
    1356                 :             : !!
    1357                 :             : !! FUNCTION
    1358                 :             : !!  Calculate values of delocalized coordinates as a function of
    1359                 :             : !!  cartesian ones. First primitive internals, then B matrix,
    1360                 :             : !!  then F, then U then delocalized internals.
    1361                 :             : !!
    1362                 :             : !! INPUTS
    1363                 :             : !! deloc <type(delocint)>=Important variables for pred_delocint
    1364                 :             : !!   |
    1365                 :             : !!   | nang     = Number of angles
    1366                 :             : !!   | nbond    = Number of bonds
    1367                 :             : !!   | ncart    = Number of cartesian directions
    1368                 :             : !!   |             (used for constraints)
    1369                 :             : !!   | ndihed   = Number of dihedrals
    1370                 :             : !!   | nrshift  = Dimension of rshift
    1371                 :             : !!   | ninternal= Number of internal coordinates
    1372                 :             : !!   |            ninternal=nbond+nang+ndihed+ncart
    1373                 :             : !!   |
    1374                 :             : !!   | angs(2,3,nang)  = Indexes to characterize angles
    1375                 :             : !!   | bonds(2,2,nbond)= For a bond between iatom and jatom
    1376                 :             : !!   |                   bonds(1,1,nbond) = iatom
    1377                 :             : !!   |                   bonds(2,1,nbond) = icenter
    1378                 :             : !!   |                   bonds(1,2,nbond) = jatom
    1379                 :             : !!   |                   bonds(2,2,nbond) = irshift
    1380                 :             : !!   | carts(2,ncart)  = Index of total primitive internal,
    1381                 :             : !!   |                   and atom (carts(2,:))
    1382                 :             : !!   | dihedrals(2,4,ndihed)= Indexes to characterize dihedrals
    1383                 :             : !!   |
    1384                 :             : !!   | rshift(3,nrshift)= Shift in xred that must be done to find
    1385                 :             : !!   |                    all neighbors of a given atom within a
    1386                 :             : !!   |                    given number of neighboring shells
    1387                 :             : !! natom = Number of atoms
    1388                 :             : !! rprimd(3,3) = Dimensional real space primitive translations
    1389                 :             : !!               (bohr)
    1390                 :             : !! xcart(3,natom) = Cartesian coordinates of atoms (bohr)
    1391                 :             : !!
    1392                 :             : !! OUTPUT
    1393                 :             : !! bt_inv_matrix(3*(natom-1),3*natom) = Inverse of B^{T} matrix
    1394                 :             : !! deloc_int(3*(natom-1)) = Delocalized internal coordinates
    1395                 :             : !! prim_int(ninternal) = Primitive internal coordinates
    1396                 :             : !!
    1397                 :             : !! SIDE EFFECTS
    1398                 :             : !! u_matrix(ninternal,3*(natom-1)) = Eigenvectors of BB^T matrix
    1399                 :             : !!
    1400                 :             : !! NOTES
    1401                 :             : !!
    1402                 :             : !! SOURCE
    1403                 :             : 
    1404                 :          64 : subroutine xcart2deloc(deloc,natom,rprimd,xcart,bt_inv_matrix,u_matrix,deloc_int,prim_int)
    1405                 :             : 
    1406                 :             : !Arguments ------------------------------------
    1407                 :             : !scalars
    1408                 :             :  integer,intent(in) :: natom
    1409                 :             :  type(delocint),intent(in) :: deloc
    1410                 :             : !arrays
    1411                 :             :  real(dp),intent(in) :: rprimd(3,3),xcart(3,natom)
    1412                 :             :  real(dp),intent(inout) :: u_matrix(deloc%ninternal,3*(natom-1))
    1413                 :             :  real(dp),intent(out) :: bt_inv_matrix(3*(natom-1),3*natom)
    1414                 :             :  real(dp),intent(out) :: deloc_int(3*(natom-1))
    1415                 :             :  real(dp),intent(out) :: prim_int(deloc%ninternal)
    1416                 :             : 
    1417                 :             : !Local variables-------------------------------
    1418                 :             : !scalars
    1419                 :             : integer :: ii
    1420                 :             : logical :: DEBUG=.FALSE.
    1421                 :             : !arrays
    1422                 :         128 :  real(dp) :: b_matrix(deloc%ninternal,3*natom)
    1423                 :             : 
    1424                 :             : ! ******************************************************************
    1425                 :             : 
    1426                 :          64 :  call calc_prim_int(deloc,natom,rprimd,xcart,prim_int)
    1427         [ -  + ]:          64 :  if (DEBUG)then
    1428                 :           0 :    write(std_out,*) 'Primitive Internals'
    1429         [ #  # ]:           0 :    do ii=1,deloc%ninternal
    1430                 :           0 :      write(std_out,*) prim_int(ii)
    1431                 :             :    end do
    1432                 :             :  end if
    1433                 :             : 
    1434                 :          64 :  call calc_b_matrix(deloc,natom,rprimd,xcart,b_matrix)
    1435         [ -  + ]:          64 :  if (DEBUG)then
    1436                 :           0 :    write(std_out,*) 'B Matrix'
    1437         [ #  # ]:           0 :    do ii=1,deloc%ninternal
    1438                 :           0 :      write(std_out,*) b_matrix(:,ii)
    1439                 :             :    end do
    1440                 :             :  end if
    1441                 :             : 
    1442                 :             :  call calc_btinv_matrix(b_matrix,natom,deloc%ninternal,&
    1443                 :          64 : & bt_inv_matrix,u_matrix)
    1444         [ -  + ]:          64 :  if (DEBUG)then
    1445                 :           0 :    write(std_out,*) 'BT Inverse Matrix'
    1446         [ #  # ]:           0 :    do ii=1,3*natom
    1447                 :           0 :      write(std_out,*) bt_inv_matrix(:,ii)
    1448                 :             :    end do
    1449                 :             :  end if
    1450                 :             : 
    1451                 :             : !calculate value of delocalized internals
    1452                 :             : 
    1453                 :             :  call dgemv('T',deloc%ninternal,3*(natom-1),one,&
    1454                 :          64 : & u_matrix,deloc%ninternal,prim_int,1,zero,deloc_int,1)
    1455                 :             : 
    1456                 :          64 : end subroutine xcart2deloc
    1457                 :             : !!***
    1458                 :             : 
    1459                 :             : 
    1460                 :             : !!****f* ABINIT/calc_btinv_matrix
    1461                 :             : !! NAME
    1462                 :             : !! calc_btinv_matrix
    1463                 :             : !!
    1464                 :             : !! FUNCTION
    1465                 :             : !!
    1466                 :             : !! INPUTS
    1467                 :             : !!
    1468                 :             : !! OUTPUT
    1469                 :             : !!
    1470                 :             : !! NOTES
    1471                 :             : !!   bt_inv_matrix is inverse transpose of the delocalized
    1472                 :             : !!    coordinate B matrix. b_matrix is the primitive internal B matrix
    1473                 :             : !!
    1474                 :             : !! SOURCE
    1475                 :             : 
    1476                 :          64 :  subroutine calc_btinv_matrix(b_matrix,natom,ninternal,bt_inv_matrix,u_matrix)
    1477                 :             : 
    1478                 :             : !Arguments ------------------------------------
    1479                 :             :  integer,intent(in) :: ninternal,natom
    1480                 :             :  real(dp),intent(in) :: b_matrix(ninternal,3*natom)
    1481                 :             :  real(dp),intent(out) :: bt_inv_matrix(3*(natom-1),3*natom)
    1482                 :             :  real(dp),intent(inout) :: u_matrix(ninternal,3*(natom-1))
    1483                 :             : 
    1484                 :             : !Local variables ------------------------------------
    1485                 :             : !scalars
    1486                 :             :  integer :: ii,info,lwork
    1487                 :             : !arrays
    1488                 :         128 :  real(dp) :: f_eigs(3*natom),f_matrix(3*natom,3*natom)
    1489                 :         128 :  real(dp) :: s_matrix(3*natom,3*natom)
    1490                 :         128 :  real(dp) :: s_red(3*natom,3*(natom-1))
    1491                 :         128 :  real(dp) :: u_matrix_old(ninternal,3*(natom-1))
    1492                 :          64 :  real(dp),allocatable :: work(:)
    1493                 :             : 
    1494                 :             : !******************************************************************
    1495                 :             : 
    1496                 :             : !f matrix = B^{T} B
    1497                 :             :  call dgemm('T','N',3*natom,3*natom,ninternal,one,&
    1498                 :          64 : & b_matrix,ninternal,b_matrix,ninternal,zero,f_matrix,3*natom)
    1499                 :             : 
    1500                 :          64 :  lwork = max(1,3*3*natom-1)
    1501   [ -  +  +  -  :         192 :  ABI_MALLOC(work,(lwork))
          +  -  -  +  -  
                      + ]
    1502   [ +  +  +  + ]:        2752 :  s_matrix(:,:) = f_matrix(:,:)
    1503                 :             : 
    1504                 :          64 :  call dsyev('V','L',3*natom,s_matrix,3*natom,f_eigs,work,lwork,info)
    1505                 :             : 
    1506         [ -  + ]:          64 :  ABI_FREE(work)
    1507                 :             : 
    1508         [ -  + ]:          64 :  if (abs(f_eigs(1)) + abs(f_eigs(2)) + abs(f_eigs(3)) > tol10 ) then
    1509                 :           0 :    write(std_out,*) 'Error: 3 lowest eigenvalues are not zero'
    1510                 :           0 :    write(std_out,*) '  internal coordinates do NOT span the full degrees of freedom !'
    1511                 :           0 :    write(std_out,'(6E16.6)') f_eigs
    1512                 :           0 :    ABI_ERROR("Aborting now")
    1513                 :             :  end if
    1514         [ -  + ]:          64 :  if ( abs(f_eigs(4)) < tol10 ) then
    1515                 :           0 :    write(std_out,*) 'Error: fourth eigenvalue is zero'
    1516                 :           0 :    write(std_out,*) '  internal coordinates do NOT span the full degrees of freedom !'
    1517                 :           0 :    write(std_out,'(6E16.6)') f_eigs
    1518                 :           0 :    ABI_ERROR("Aborting now")
    1519                 :             :  end if
    1520                 :             : 
    1521                 :             : !calculate U matrix from U = B * S_red * lambda^{-1/2}
    1522         [ +  + ]:         256 :  do ii=1,3*(natom-1)
    1523         [ +  + ]:        1408 :    s_red(:,ii) = s_matrix(:,ii+3)/sqrt(f_eigs(ii+3))
    1524                 :             :  end do
    1525                 :             : 
    1526   [ +  +  +  + ]:       10240 :  u_matrix_old(:,:) = u_matrix(:,:)
    1527                 :             : 
    1528                 :             :  call dgemm('N','N',ninternal,3*(natom-1),3*natom,one,&
    1529                 :          64 : & b_matrix,ninternal,s_red,3*natom,zero,u_matrix,ninternal)
    1530                 :             : 
    1531                 :             : 
    1532                 :             : !align eigenvectors, to preserve a form of continuity in convergences
    1533                 :             : !!!! eigenvalues are no longer in increasing order!!! but only s_red is reordered
    1534                 :             : !so that btinv is correct.
    1535                 :          64 :  call align_u_matrices(natom,ninternal,u_matrix,u_matrix_old,s_matrix,f_eigs)
    1536                 :             : 
    1537                 :             : !calculate B_deloc^{-1} matrix for transformation of forces to deloc coord.
    1538                 :             : !(B^{T}_deloc)^{-1} = (B_deloc B^{T}_deloc)^{-1} B_deloc = lambda^{-3/2} S^{T} F
    1539                 :             : != ( S lambda^{3/2} )^{T} F
    1540                 :             : 
    1541                 :             : !! DEFINITION
    1542                 :             : !! real(dp),intent(out) :: bt_inv_matrix(3*(natom-1),3*natom)
    1543                 :             : 
    1544                 :             : !even better: B_deloc^{-1} = lambda^{-1/2} S^{T}
    1545         [ +  + ]:         256 :  do ii=1,3*(natom-1)
    1546                 :             : !  s_red(:,ii) = s_matrix(:,ii+3)*sqrt(f_eigs(ii+3))
    1547         [ +  + ]:        1408 :    bt_inv_matrix(ii,:) = s_matrix(:,ii+3)/sqrt(f_eigs(ii+3))
    1548                 :             :  end do
    1549                 :             : 
    1550                 :          64 : end subroutine calc_btinv_matrix
    1551                 :             : !!***
    1552                 :             : 
    1553                 :             : !!****f* ABINIT/align_u_matrices
    1554                 :             : !! NAME
    1555                 :             : !! align_u_matrices
    1556                 :             : !!
    1557                 :             : !! FUNCTION
    1558                 :             : !!
    1559                 :             : !! INPUTS
    1560                 :             : !!
    1561                 :             : !! OUTPUT
    1562                 :             : !!
    1563                 :             : !! SOURCE
    1564                 :             : 
    1565                 :          64 :  subroutine align_u_matrices(natom,ninternal,u_matrix,u_matrix_old,s_matrix,f_eigs)
    1566                 :             : 
    1567                 :             : !Arguments ------------------------------------
    1568                 :             : !scalars
    1569                 :             :  integer,intent(in) :: ninternal,natom
    1570                 :             : !arrays
    1571                 :             :  real(dp),intent(in) :: u_matrix_old(ninternal,3*(natom-1))
    1572                 :             :  real(dp),intent(inout) :: f_eigs(3*natom)
    1573                 :             :  real(dp),intent(inout) :: s_matrix(3*natom,3*natom)
    1574                 :             :  real(dp),intent(inout) :: u_matrix(ninternal,3*(natom-1))
    1575                 :             : 
    1576                 :             : !Local variables ------------------------------
    1577                 :             : !scalars
    1578                 :             :  integer :: ii,iint1,imax
    1579                 :             :  real(dp) :: ss
    1580                 :             : !arrays
    1581                 :         128 :  integer :: eigv_flag(3*(natom-1)),eigv_ind(3*(natom-1))
    1582                 :         128 :  real(dp) :: tmps(3*natom,3*natom)
    1583                 :         128 :  real(dp) :: tmpu(ninternal,3*(natom-1))
    1584                 :          64 :  real(dp) :: tmpf(3*natom)
    1585                 :             : 
    1586                 :             : !******************************************************************
    1587                 :             : 
    1588         [ +  + ]:         256 :  eigv_flag(:) = 0
    1589         [ +  + ]:         256 :  eigv_ind(:) = 0
    1590                 :             : 
    1591                 :             : !just permit a change in sign
    1592         [ +  + ]:         256 :  do iint1=1,3*(natom-1)
    1593                 :             :    ss = zero
    1594         [ +  + ]:       10176 :    do ii=1,ninternal
    1595                 :       10176 :      ss = ss + u_matrix_old(ii,iint1)*u_matrix(ii,iint1)
    1596                 :             :    end do
    1597         [ -  + ]:         192 :    if (ss < -tol12) then
    1598                 :           0 :      imax = -iint1
    1599                 :             :    else
    1600                 :             :      imax = iint1
    1601                 :             :    end if
    1602                 :         192 :    eigv_ind(iint1) = imax
    1603                 :         256 :    eigv_flag(abs(imax)) = 1
    1604                 :             :  end do
    1605                 :             : 
    1606   [ +  +  +  + ]:       10240 :  tmpu(:,:) = u_matrix
    1607   [ +  +  +  + ]:        2752 :  tmps(:,:) = s_matrix
    1608         [ +  + ]:         448 :  tmpf(:) = f_eigs
    1609                 :             : !exchange eigenvectors...
    1610         [ +  + ]:         256 :  do iint1=1,3*(natom-1)
    1611                 :         192 :    ss = one
    1612         [ -  + ]:         192 :    if (eigv_ind(iint1) < 0) ss = -one
    1613                 :             : 
    1614                 :         192 :    imax = abs(eigv_ind(iint1))
    1615                 :             : 
    1616         [ +  + ]:       10176 :    tmpu(:,imax) = ss*u_matrix(:,iint1)
    1617                 :             : 
    1618         [ +  + ]:        1344 :    tmps(:,imax+3) = ss*s_matrix(:,iint1+3)
    1619                 :             : 
    1620                 :         256 :    tmpf(imax+3) = f_eigs(iint1+3)
    1621                 :             :  end do
    1622                 :             : 
    1623   [ +  +  +  + ]:       10240 :  u_matrix(:,:) = tmpu(:,:)
    1624   [ +  +  +  + ]:        2752 :  s_matrix(:,:) = tmps(:,:)
    1625         [ +  + ]:         448 :  f_eigs(:) = tmpf(:)
    1626                 :             : 
    1627                 :          64 : end subroutine align_u_matrices
    1628                 :             : !!***
    1629                 :             : 
    1630                 :             : !!****f* ABINIT/xfh_recover_deloc
    1631                 :             : !! NAME
    1632                 :             : !! xfh_recover_deloc
    1633                 :             : !!
    1634                 :             : !! FUNCTION
    1635                 :             : !! Update the contents of the history xfhist taking values
    1636                 :             : !! from xred, acell, rprim, gred_corrected and strten
    1637                 :             : !!
    1638                 :             : !! INPUTS
    1639                 :             : !!
    1640                 :             : !! OUTPUT
    1641                 :             : !!
    1642                 :             : !! SOURCE
    1643                 :             : 
    1644                 :           0 : subroutine xfh_recover_deloc(ab_xfh,ab_mover,acell,cycl_main,&
    1645                 :           0 : & gred,hessin,ndim,rprim,rprimd0,strten,ucvol,ucvol0,vin,vin_prev,&
    1646   [ #  #  #  #  :           0 : & vout,vout_prev,xred,deloc,deloc_int,deloc_gred,btinv,gprimd,prim_int,&
          #  #  #  #  #  
                      # ]
    1647   [ #  #  #  # ]:           0 : & u_matrix)
    1648                 :             : 
    1649                 :             : !Arguments ------------------------------------
    1650                 :             : !scalars
    1651                 :             : 
    1652                 :             : integer,intent(in) :: ndim
    1653                 :             : integer,intent(out) :: cycl_main
    1654                 :             : real(dp),intent(inout) :: ucvol,ucvol0
    1655                 :             : type(ab_xfh_type),intent(inout) :: ab_xfh
    1656                 :             : type(abimover),intent(in) :: ab_mover
    1657                 :             : ! DELOCINT specials
    1658                 :             : type(delocint),intent(in) :: deloc
    1659                 :             : 
    1660                 :             : !arrays
    1661                 :             : real(dp),intent(inout) :: acell(3)
    1662                 :             : real(dp),intent(inout) :: hessin(:,:)
    1663                 :             : real(dp),intent(inout) :: xred(3,ab_mover%natom)
    1664                 :             : real(dp),intent(inout) :: rprim(3,3)
    1665                 :             : real(dp),intent(inout) :: rprimd0(3,3)
    1666                 :             : real(dp),intent(inout) :: gred(3,ab_mover%natom)
    1667                 :             : real(dp),intent(inout) :: strten(6)
    1668                 :             : real(dp),intent(inout) :: vin(:)
    1669                 :             : real(dp),intent(inout) :: vin_prev(:)
    1670                 :             : real(dp),intent(inout) :: vout(:)
    1671                 :             : real(dp),intent(inout) :: vout_prev(:)
    1672                 :             : ! DELOCINT specials
    1673                 :             : real(dp),intent(inout) :: deloc_gred(3*(ab_mover%natom-1))
    1674                 :             : real(dp),intent(inout) :: deloc_int(3*(ab_mover%natom-1))
    1675                 :             : real(dp),intent(inout) :: btinv(3*(ab_mover%natom-1),3*ab_mover%natom)
    1676                 :             : real(dp),intent(inout) :: prim_int(:),u_matrix(:,:),gprimd(3,3)
    1677                 :             : 
    1678                 :             : !Local variables-------------------------------
    1679                 :             : !scalars
    1680                 :             : integer :: ixfh
    1681                 :           0 : real(dp) :: xcart(3,ab_mover%natom)
    1682                 :             : 
    1683                 :             : !*********************************************************************
    1684                 :             : 
    1685         [ #  # ]:           0 :  if(ab_xfh%nxfh/=0)then
    1686                 :             : !  Loop over previous time steps
    1687         [ #  # ]:           0 :    do ixfh=1,ab_xfh%nxfh
    1688                 :             : 
    1689                 :             : !    For that time step, get new (x,f) from xfhist
    1690   [ #  #  #  # ]:           0 :      xred(:,:)     =ab_xfh%xfhist(:,1:ab_mover%natom        ,1,ixfh)
    1691   [ #  #  #  # ]:           0 :      rprim(1:3,1:3)=ab_xfh%xfhist(:,ab_mover%natom+2:ab_mover%natom+4,1,ixfh)
    1692         [ #  # ]:           0 :      acell(:)      =ab_xfh%xfhist(:,ab_mover%natom+1,1,ixfh)
    1693   [ #  #  #  # ]:           0 :      gred(:,:)     =ab_xfh%xfhist(:,1:ab_mover%natom,2,ixfh)
    1694                 :             : !    This use of results_gs is unusual
    1695         [ #  # ]:           0 :      strten(1:3)   =ab_xfh%xfhist(:,ab_mover%natom+2,2,ixfh)
    1696         [ #  # ]:           0 :      strten(4:6)   =ab_xfh%xfhist(:,ab_mover%natom+3,2,ixfh)
    1697                 :             : 
    1698                 :             : !    !DEBUG
    1699                 :             : !    write (ab_out,*) '---READ FROM XFHIST---'
    1700                 :             : 
    1701                 :             : !    write (ab_out,*) 'XRED'
    1702                 :             : !    do kk=1,ab_mover%natom
    1703                 :             : !    write (ab_out,*) xred(:,kk)
    1704                 :             : !    end do
    1705                 :             : !    write (ab_out,*) 'FRED'
    1706                 :             : !    do kk=1,ab_mover%natom
    1707                 :             : !    write (ab_out,*) gred(:,kk)
    1708                 :             : !    end do
    1709                 :             : !    write(ab_out,*) 'RPRIM'
    1710                 :             : !    do kk=1,3
    1711                 :             : !    write(ab_out,*) rprim(:,kk)
    1712                 :             : !    end do
    1713                 :             : !    write(ab_out,*) 'ACELL'
    1714                 :             : !    write(ab_out,*) acell(:)
    1715                 :             : !    !DEBUG
    1716                 :             : 
    1717                 :             : !    Convert input xred (reduced coordinates) to xcart (cartesian)
    1718                 :           0 :      call xred2xcart(ab_mover%natom,rprimd0,xcart,xred)
    1719                 :             : !    Convert input coordinates in Delocalized internals
    1720                 :             :      call xcart2deloc(deloc,ab_mover%natom,rprimd0,xcart,&
    1721   [ #  #  #  #  :           0 : &     btinv,u_matrix,deloc_int,prim_int)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1722                 :             : !    Convert forces to delocalized coordinates for next step
    1723                 :           0 :      call gred2gdeloc(btinv,deloc_gred,gred,ab_mover%natom,gprimd)
    1724                 :             : 
    1725                 :             : !    Transfer it in vin, vout
    1726                 :             :      call xfpack_x2vin(acell,ab_mover%natom-1,&
    1727                 :             : &     ndim,ab_mover%nsym,ab_mover%optcell,rprim,rprimd0,&
    1728   [ #  #  #  #  :           0 : &     ab_mover%symrel,ucvol,ucvol0,vin,deloc_int)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1729                 :             :      call xfpack_f2vout(deloc_gred,ab_mover%natom-1,&
    1730                 :             : &     ndim,ab_mover%optcell,ab_mover%strtarget,strten,&
    1731   [ #  #  #  #  :           0 : &     ucvol,vout)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1732                 :             : !    Get old time step, if any, and update inverse hessian
    1733         [ #  # ]:           0 :      if(ixfh/=1)then
    1734   [ #  #  #  # ]:           0 :        xred(:,:)     =ab_xfh%xfhist(:,1:ab_mover%natom,1,ixfh-1)
    1735                 :             :        rprim(1:3,1:3)=&
    1736   [ #  #  #  # ]:           0 : &       ab_xfh%xfhist(:,ab_mover%natom+2:ab_mover%natom+4,1,ixfh-1)
    1737         [ #  # ]:           0 :        acell(:)=ab_xfh%xfhist(:,ab_mover%natom+1,1,ixfh-1)
    1738   [ #  #  #  # ]:           0 :        gred(:,:)=ab_xfh%xfhist(:,1:ab_mover%natom,2,ixfh-1)
    1739                 :             : !      This use of results_gs is unusual
    1740         [ #  # ]:           0 :        strten(1:3)=ab_xfh%xfhist(:,ab_mover%natom+2,2,ixfh-1)
    1741         [ #  # ]:           0 :        strten(4:6)=ab_xfh%xfhist(:,ab_mover%natom+3,2,ixfh-1)
    1742                 :             : 
    1743                 :             : !      Convert input xred (reduced coordinates) to xcart (cartesian)
    1744                 :           0 :        call xred2xcart(ab_mover%natom,rprimd0,xcart,xred)
    1745                 :             : !      Convert input coordinates in Delocalized internals
    1746                 :             :        call xcart2deloc(deloc,ab_mover%natom,rprimd0,xcart,&
    1747   [ #  #  #  #  :           0 : &       btinv,u_matrix,deloc_int,prim_int)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1748                 :             : !      Convert forces to delocalized coordinates for next step
    1749                 :           0 :        call gred2gdeloc(btinv,deloc_gred,gred,ab_mover%natom,gprimd)
    1750                 :             : 
    1751                 :             : !      Tranfer it in vin_prev, vout_prev
    1752                 :             :        call xfpack_x2vin(acell,ab_mover%natom-1,&
    1753                 :             : &       ndim,ab_mover%nsym,ab_mover%optcell,rprim,rprimd0,&
    1754   [ #  #  #  #  :           0 : &       ab_mover%symrel,ucvol,ucvol0,vin_prev,deloc_int)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1755                 :             :        call xfpack_f2vout(deloc_gred,ab_mover%natom-1,&
    1756                 :             : &       ndim,ab_mover%optcell,ab_mover%strtarget,strten,&
    1757   [ #  #  #  #  :           0 : &       ucvol,vout_prev)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1758                 :             : 
    1759                 :             : !      write(ab_out,*) 'Hessian matrix before update',ndim,'x',ndim
    1760                 :             : !      write(ab_out,*) 'ixfh=',ixfh
    1761                 :             : !      do kk=1,ndim
    1762                 :             : !      do jj=1,ndim,3
    1763                 :             : !      if (jj+2<=ndim)then
    1764                 :             : !      write(ab_out,*) jj,hessin(jj:jj+2,kk)
    1765                 :             : !      else
    1766                 :             : !      write(ab_out,*) jj,hessin(jj:ndim,kk)
    1767                 :             : !      end if
    1768                 :             : !      end do
    1769                 :             : !      end do
    1770                 :             : 
    1771                 :             :        call hessupdt(hessin,ab_mover%iatfix,ab_mover%natom-1,ndim,&
    1772   [ #  #  #  #  :           0 : &       vin,vin_prev,vout,vout_prev)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1773                 :             : 
    1774                 :             : !      !DEBUG
    1775                 :             : !      write(ab_out,*) 'Hessian matrix after update',ndim,'x',ndim
    1776                 :             : !      do kk=1,ndim
    1777                 :             : !      do jj=1,ndim,3
    1778                 :             : !      if (jj+2<=ndim)then
    1779                 :             : !      write(ab_out,*) jj,hessin(jj:jj+2,kk)
    1780                 :             : !      else
    1781                 :             : !      write(ab_out,*) jj,hessin(jj:ndim,kk)
    1782                 :             : !      end if
    1783                 :             : !      end do
    1784                 :             : !      end do
    1785                 :             : !      !DEBUG
    1786                 :             : 
    1787                 :             :      end if !if(ab_xfh%nxfh/=0)
    1788                 :             : 
    1789                 :             : !    End loop over previous time steps
    1790                 :             :    end do
    1791                 :             : 
    1792                 :             : !  The hessian has been generated,
    1793                 :             : !  as well as the latest vin and vout
    1794                 :             : !  so will cycle the main loop
    1795                 :           0 :    cycl_main=1
    1796                 :             : 
    1797                 :             :  end if
    1798                 :             : 
    1799                 :           0 : end subroutine xfh_recover_deloc
    1800                 :             : !!***
    1801                 :             : 
    1802         [ -  + ]:           1 : end module m_pred_delocint
    1803                 :             : !!***
        

Generated by: LCOV version 2.3-1