LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_pred_diisrelax.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 165 0
Test Date: 2026-11-06 14:42:53 Functions: 0.0 % 1 0
Branches: 0.0 % 310 0

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_pred_diisrelax
       2                 :             : !! NAME
       3                 :             : !!  m_pred_diisrelax
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, JCC, SE)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_pred_diisrelax
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_abimover
      27                 :             :  use m_abihist
      28                 :             :  use m_linalg_interfaces
      29                 :             : 
      30                 :             :  use m_geometry,  only : xcart2xred, xred2xcart
      31                 :             :  use m_bfgs, only : hessinit, hessupdt
      32                 :             : 
      33                 :             :  implicit none
      34                 :             : 
      35                 :             :  private
      36                 :             : !!***
      37                 :             : 
      38                 :             :  public :: pred_diisrelax
      39                 :             : !!***
      40                 :             : 
      41                 :             : contains
      42                 :             : !!***
      43                 :             : 
      44                 :             : !!****f* ABINIT/pred_diisrelax
      45                 :             : !! NAME
      46                 :             : !! pred_diisrelax
      47                 :             : !!
      48                 :             : !! FUNCTION
      49                 :             : !! Ionmov predictor (20) Direct inversion of the iterative subspace
      50                 :             : !!
      51                 :             : !! IONMOV 20:
      52                 :             : !! Given a starting point xred that is a vector of length 3*natom
      53                 :             : !! (reduced nuclei coordinates), and unit cell parameters (rprimd)
      54                 :             : !! this routine uses the DIIS (direct inversion of the iterative
      55                 :             : !! subspace) to minize the gradient (forces) on atoms. The preconditioning
      56                 :             : !! used to compute errors from gradients is using an inversed hessian
      57                 :             : !! matrix obtained by a BFGS algorithm.
      58                 :             : !! This method is known to converge to the nearest point where gradients
      59                 :             : !! vanish. This is efficient to refine positions around a saddle point
      60                 :             : !! for instance.
      61                 :             : !!
      62                 :             : !! INPUTS
      63                 :             : !! ab_mover <type(abimover)> : Datatype with all the information needed by the preditor
      64                 :             : !! itime  : Index of the present iteration
      65                 :             : !! ntime  : Maximal number of iterations
      66                 :             : !! zDEBUG : if true print some debugging information
      67                 :             : !!
      68                 :             : !! OUTPUT
      69                 :             : !!
      70                 :             : !! SIDE EFFECTS
      71                 :             : !! hist <type(abihist)> : History of positions,forces,acell, rprimd, stresses
      72                 :             : !!
      73                 :             : !! SOURCE
      74                 :             : 
      75                 :           0 : subroutine pred_diisrelax(ab_mover,hist,itime,ntime,zDEBUG,iexit)
      76                 :             : 
      77                 :             : !Arguments ------------------------------------
      78                 :             : !scalars
      79                 :             :  integer,intent(in) :: itime
      80                 :             :  integer,intent(in) :: ntime
      81                 :             :  integer,intent(in) :: iexit
      82                 :             :  logical,intent(in) :: zDEBUG
      83                 :             :  type(abimover),intent(in) :: ab_mover
      84                 :             :  type(abihist),intent(inout),target :: hist
      85                 :             : 
      86                 :             : !Local variables-------------------------------
      87                 :             : !scalars
      88                 :             :  integer  :: ihist_prev,ndim,nhist,shift,diisSize
      89                 :             :  integer  :: ii,jj,kk,info
      90                 :             :  real(dp) :: etotal
      91                 :             :  real(dp) :: suma
      92                 :             : !arrays
      93                 :             :  real(dp) :: acell(3)
      94                 :             :  real(dp) :: rprimd(3,3)
      95                 :           0 :  real(dp) :: xred(3,ab_mover%natom)
      96                 :           0 :  real(dp) :: xcart(3,ab_mover%natom)
      97                 :             :  real(dp) :: strten(6)
      98                 :             :  real(dp) ::  ident(3,3)
      99                 :             :  real(dp),allocatable,save :: hessin(:,:)
     100                 :             : ! DIISRELAX SPECIFIC
     101                 :             : ! error:          Store the supposed error
     102                 :             : !                 steps. it is required to compute the DIIS matrix.
     103                 :             : ! diisMatrix:     Store the matrix used to compute the coefficients.
     104                 :             : ! diisCoeff:      Store the coefficients computed from diisMatrix.
     105                 :             : ! workMatrix:     Lapack work array.
     106                 :             : ! workArray:      Lapack work array.
     107                 :             : ! ipiv:           Lapack work array.
     108                 :           0 :  integer,  allocatable :: ipiv(:)
     109                 :           0 :  real(dp) :: fcart_tmp(3*ab_mover%natom)
     110                 :           0 :  real(dp) :: error_tmp(3*ab_mover%natom)
     111         [ #  # ]:           0 :  real(dp) :: xcart_tmp(3*ab_mover%natom)
     112                 :             :  real(dp), allocatable,save :: error(:, :, :)
     113                 :           0 :  real(dp), allocatable :: xcart_hist(:,:,:)
     114                 :           0 :  real(dp), allocatable :: diisMatrix(:, :)
     115                 :           0 :  real(dp), allocatable :: diisCoeff(:)
     116                 :           0 :  real(dp), allocatable :: workArray(:)
     117                 :           0 :  real(dp), allocatable :: workMatrix(:, :)
     118                 :           0 :  real(dp),pointer :: fcart_hist(:,:,:)
     119                 :             : 
     120                 :             : !***************************************************************************
     121                 :             : !Beginning of executable session
     122                 :             : !***************************************************************************
     123                 :             : 
     124                 :           0 :  if(iexit/=0)then
     125                 :             :    ABI_SFREE(ipiv)
     126         [ #  # ]:           0 :    ABI_SFREE(error)
     127                 :             :    ABI_SFREE(diisMatrix)
     128                 :             :    ABI_SFREE(diisCoeff)
     129                 :             :    ABI_SFREE(workArray)
     130                 :             :    ABI_SFREE(workMatrix)
     131         [ #  # ]:           0 :    ABI_SFREE(hessin)
     132                 :           0 :    return
     133                 :             :  end if
     134                 :             : 
     135                 :             : !write(std_out,*) 'diisrelax 01'
     136                 :             : !##########################################################
     137                 :             : !### 01. Debugging and Verbose
     138                 :             : 
     139         [ #  # ]:           0 :  if(zDEBUG)then
     140         [ #  # ]:           0 :    write(std_out,'(a,3a,40a,37a)') ch10,('-',kk=1,3),&
     141   [ #  #  #  #  :           0 : &   'Debugging and Verbose for pred_diisrelax',('-',kk=1,37)
                   #  # ]
     142                 :           0 :    write(std_out,*) 'ionmov: ',20
     143                 :           0 :    write(std_out,*) 'itime:  ',itime
     144                 :             :  end if
     145                 :             : 
     146                 :             : !write(std_out,*) 'diisrelax 02'
     147                 :             : !##########################################################
     148                 :             : !### 02. Compute the dimension of vectors (ndim=3*natom)
     149                 :             : 
     150                 :           0 :  ndim=3*ab_mover%natom
     151                 :           0 :  nhist=hist%mxhist
     152                 :             : 
     153         [ #  # ]:           0 :  if(zDEBUG) write(std_out,*) 'Dimension of vin, vout and hessian (ndim): ',ndim
     154                 :             : 
     155                 :             : !write(std_out,*) 'diisrelax 03'
     156                 :             : !##########################################################
     157                 :             : !### 03. Allocate the arrays
     158                 :             : 
     159                 :             : !Notice that the arrays could be allocated
     160                 :             : !From a previous dataset with a different ndim
     161         [ #  # ]:           0 :  if(itime==1)then
     162         [ #  # ]:           0 :    ABI_SFREE(error)
     163         [ #  # ]:           0 :    ABI_SFREE(hessin)
     164                 :             : 
     165   [ #  #  #  #  :           0 :    ABI_MALLOC(error,(3, ab_mover%natom, nhist))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     166   [ #  #  #  #  :           0 :    ABI_MALLOC(hessin,(ndim,ndim))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     167                 :             : 
     168                 :           0 :    ident(:, :) = zero
     169                 :           0 :    ident(1, 1) = -one
     170                 :           0 :    ident(2, 2) = -one
     171                 :           0 :    ident(3, 3) = -one
     172                 :           0 :    call hessinit(ab_mover,hessin,ident,ndim,zero)
     173                 :             : 
     174                 :             :  end if
     175                 :             : 
     176                 :             : !write(std_out,*) 'diisrelax 04'
     177                 :             : !##########################################################
     178                 :             : !### 04. Compute the shift in the history and the size
     179                 :             : !###     of the diisMatrix
     180                 :             : 
     181                 :             : !When itime > diismemory we need to shift the records
     182                 :             : !in the history to obtain the right values, the variable
     183                 :             : !'shift' contains the actual shift to be applied on each
     184                 :             : !iteration
     185                 :             : 
     186                 :           0 :  shift=max(0,itime-ab_mover%diismemory)
     187                 :             : 
     188                 :             : !Initially the diisMatrix grows with the iteration itime
     189                 :             : !(itime+1) but when it arrives diismemory, the value of the
     190                 :             : !matrix will be fixed on (diismemory+1)
     191                 :             : 
     192         [ #  # ]:           0 :  if (ab_mover%diismemory>itime)then
     193                 :           0 :    diisSize=itime
     194                 :             :  else
     195                 :           0 :    diisSize=ab_mover%diismemory
     196                 :             :  end if
     197                 :             : 
     198                 :             : 
     199                 :             : !write(std_out,*) 'diisrelax 05'
     200                 :             : !##########################################################
     201                 :             : !### 05. Obtain the present values from the history
     202                 :             : 
     203                 :           0 :  call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     204                 :             : 
     205         [ #  # ]:           0 :  strten(:)=hist%strten(:,hist%ihist)
     206                 :           0 :  etotal   =hist%etot(hist%ihist)
     207                 :             : 
     208         [ #  # ]:           0 :  if(zDEBUG)then
     209                 :           0 :    write (std_out,*) 'fcart:'
     210         [ #  # ]:           0 :    do kk=1,ab_mover%natom
     211                 :           0 :      write (std_out,*) hist%fcart(:,kk,hist%ihist)
     212                 :             :    end do
     213                 :           0 :    write (std_out,*) 'strten:'
     214                 :           0 :    write (std_out,*) strten(1:3),ch10,strten(4:6)
     215                 :           0 :    write (std_out,*) 'etotal:'
     216                 :           0 :    write (std_out,*) etotal
     217                 :             :  end if
     218                 :             : 
     219                 :             : !Need also history in cartesian coordinates
     220   [ #  #  #  #  :           0 :  ABI_MALLOC(xcart_hist,(3,ab_mover%natom,diisSize))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     221         [ #  # ]:           0 :  do ii=1,diisSize
     222                 :           0 :    call xred2xcart(ab_mover%natom,rprimd,xcart_hist(:,:,ii),hist%xred(:,:,ii+shift))
     223                 :             :  end do
     224                 :           0 :  fcart_hist => hist%fcart(:,:,1+shift:diisSize+shift)
     225                 :             : 
     226                 :             : !write(std_out,*) 'diisrelax 06'
     227                 :             : !##########################################################
     228                 :             : !### 06. Precondition the error using the hessian matrix.
     229                 :             : 
     230                 :             : !Precondition the error using the hessian matrix.
     231                 :             : !In the quadratic approximation, we have:
     232                 :             : !e = H^-1.g, where e is the error vectors, H the hessian
     233                 :             : !and g the gradient.
     234                 :             : 
     235         [ #  # ]:           0 :  if(zDEBUG)then
     236                 :           0 :    write (std_out,*) 'Stored xcart:'
     237         [ #  # ]:           0 :    do ii = 1, diisSize, 1
     238                 :           0 :      write (std_out,*) 'ii,diisSize,shift',ii,diisSize,shift
     239         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     240                 :           0 :        write (std_out,*) xcart_hist(:,kk,ii)
     241                 :             :      end do
     242                 :             :    end do
     243                 :           0 :    write (std_out,*) 'Stored fcart'
     244         [ #  # ]:           0 :    do ii = 1, diisSize, 1
     245                 :           0 :      write (std_out,*) 'ii,diisSize,shift',ii,diisSize,shift
     246         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     247                 :           0 :        write (std_out,*) fcart_hist(:,kk,ii)
     248                 :             :      end do
     249                 :             :    end do
     250                 :             :  end if
     251                 :             : 
     252         [ #  # ]:           0 :  do ii=1,diisSize,1
     253         [ #  # ]:           0 :    fcart_tmp(:)=RESHAPE( fcart_hist(:,:,ii), (/ ndim /) )
     254                 :             : !  *  BLAS ROUTINE LEVEL 2
     255                 :             : !  *  DGEMV  performs one of the matrix-vector operations
     256                 :             : !  *
     257                 :             : !  *     y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,
     258                 :             : !  *
     259                 :             : !  *  where alpha and beta are scalars, x and y are vectors and A is an
     260                 :             : !  *  m by n matrix.
     261                 :             : 
     262                 :             : !  Here we are computing:
     263                 :             : !  error(ndim) := 1*hessin(ndim x ndim)*fcart(ndim) + 0*error(ndim)
     264                 :             : !
     265                 :             :    call DGEMV('N',ndim,ndim,one,hessin,&
     266                 :           0 : &   ndim,fcart_tmp,1,zero,error_tmp,1)
     267         [ #  # ]:           0 :    error(:,:,ii)=RESHAPE( error_tmp, (/ 3, ab_mover%natom /) )
     268                 :             : 
     269         [ #  # ]:           0 :    if(zDEBUG)then
     270                 :           0 :      write (std_out,*) 'Precondition ',ii
     271                 :           0 :      write (std_out,*) 'fcart_tmp:'
     272         [ #  # ]:           0 :      do kk=1,3*ab_mover%natom
     273                 :           0 :        write (std_out,*) fcart_tmp(kk)
     274                 :             :      end do
     275                 :           0 :      write (std_out,*) 'error:'
     276         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     277                 :           0 :        write (std_out,*) error(:,kk,ii)
     278                 :             :      end do
     279                 :           0 :      write(std_out,*) 'Hessian matrix (hessin):',ndim,'x',ndim
     280         [ #  # ]:           0 :      do kk=1,ndim
     281   [ #  #  #  # ]:           0 :        do jj=1,ndim,3
     282         [ #  # ]:           0 :          if (jj+2<=ndim)then
     283                 :           0 :            write(std_out,'(I3,1p,3e22.14)') jj,hessin(jj:jj+2,kk)
     284                 :             :          else
     285                 :           0 :            write(std_out,'(I3,1p,3e22.14)') jj,hessin(jj:ndim,kk)
     286                 :             :          end if
     287                 :             :        end do
     288                 :             :      end do
     289                 :             :    end if
     290                 :             : 
     291                 :             :  end do
     292                 :             : 
     293         [ #  # ]:           0 :  if(zDEBUG)then
     294                 :           0 :    write (std_out,*) 'Computed error'
     295         [ #  # ]:           0 :    do ii = 1, diisSize, 1
     296                 :           0 :      write (std_out,*) 'ii,diisSize,shift',ii,diisSize,shift
     297         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     298                 :           0 :        write (std_out,*) error(:,kk,ii+shift)
     299                 :             :      end do
     300                 :             :    end do
     301                 :             :  end if
     302                 :             : 
     303                 :             : !write(std_out,*) 'diisrelax 07'
     304                 :             : !##########################################################
     305                 :             : !### 07. Create the DIIS Matrix
     306                 :             : 
     307   [ #  #  #  #  :           0 :  ABI_MALLOC(diisMatrix,(diisSize + 1, diisSize + 1))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     308   [ #  #  #  # ]:           0 :  diisMatrix(:,:) = zero
     309         [ #  # ]:           0 :  if(zDEBUG) write(std_out,*) "DIIS matrix", diisSize+1,'x',diisSize+1
     310         [ #  # ]:           0 :  do ii = 1, diisSize, 1
     311         [ #  # ]:           0 :    do jj = ii, diisSize, 1
     312                 :             :      diisMatrix(jj, ii) = ddot(ndim, error(1,1,ii),&
     313                 :           0 : &     1, error(1,1,jj),1)
     314                 :           0 :      diisMatrix(ii, jj) = diisMatrix(jj, ii)
     315                 :             :    end do
     316                 :           0 :    diisMatrix(ii, diisSize + 1) = -one
     317                 :           0 :    diisMatrix(diisSize + 1, ii) = -one
     318         [ #  # ]:           0 :    if(zDEBUG) write(std_out,*) diisMatrix(1:diisSize + 1, ii)
     319                 :             :  end do
     320                 :             : 
     321                 :             : !write(std_out,*) 'diisrelax 08'
     322                 :             : !##########################################################
     323                 :             : !### 08. Solve the system using Lapack
     324                 :             : 
     325   [ #  #  #  #  :           0 :  ABI_MALLOC(diisCoeff,(diisSize + 1))
          #  #  #  #  #  
                #  #  # ]
     326         [ #  # ]:           0 :  diisCoeff(:) = zero
     327                 :           0 :  diisCoeff(diisSize + 1) = -one
     328         [ #  # ]:           0 :  if(zDEBUG) write(std_out,*) "B vector:", diisCoeff(1:diisSize + 1)
     329   [ #  #  #  #  :           0 :  ABI_MALLOC(workMatrix,(diisSize + 1, diisSize + 1))
          #  #  #  #  #  
                #  #  # ]
     330   [ #  #  #  #  :           0 :  ABI_MALLOC(workArray,((diisSize + 1) ** 2))
          #  #  #  #  #  
                #  #  # ]
     331   [ #  #  #  #  :           0 :  ABI_MALLOC(ipiv,(diisSize + 1))
          #  #  #  #  #  
                #  #  # ]
     332                 :             : !*     DCOPY(N,DX,INCX,DY,INCY)
     333                 :             : !*     copies a vector, x, to a vector, y.
     334                 :             : !*     uses unrolled loops for increments equal to one.
     335   [ #  #  #  #  :           0 :  call DCOPY((diisSize + 1) ** 2, diisMatrix(1:diisSize + 1, 1:diisSize + 1), 1, workMatrix, 1)
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     336                 :             : 
     337                 :             : !*     DSYSV( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, LWORK, INFO )
     338                 :             : !*
     339                 :             : !*  Purpose
     340                 :             : !*  =======
     341                 :             : !*
     342                 :             : !*  DSYSV computes the solution to a real system of linear equations
     343                 :             : !*     A * X = B,
     344                 :             : !*  where A is an N-by-N symmetric matrix and X and B are N-by-NRHS
     345                 :             : !*  matrices.
     346                 :             : !*
     347                 :             : !*  The diagonal pivoting method is used to factor A as
     348                 :             : !*     A = U * D * U**T,  if UPLO = 'U', or
     349                 :             : !*     A = L * D * L**T,  if UPLO = 'L',
     350                 :             : !*  where U (or L) is a product of permutation and unit upper (lower)
     351                 :             : !*  triangular matrices, and D is symmetric and block diagonal with
     352                 :             : !*  1-by-1 and 2-by-2 diagonal blocks.  The factored form of A is then
     353                 :             : !*  used to solve the system of equations A * X = B.
     354                 :             : !*
     355                 :             : !*  Arguments
     356                 :             : !*  =========
     357                 :             : !*
     358                 :             : !*  UPLO    (input) CHARACTER*1
     359                 :             : !*          = 'U':  Upper triangle of A is stored;
     360                 :             : !*          = 'L':  Lower triangle of A is stored.
     361                 :             : !*
     362                 :             : !*  N       (input) INTEGER
     363                 :             : !*          The number of linear equations, i.e., the order of the
     364                 :             : !*          matrix A.  N >= 0.
     365                 :             : !*
     366                 :             : !*  NRHS    (input) INTEGER
     367                 :             : !*          The number of right hand sides, i.e., the number of columns
     368                 :             : !*          of the matrix B.  NRHS >= 0.
     369                 :             : !*
     370                 :             : !*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
     371                 :             : !*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
     372                 :             : !*          N-by-N upper triangular part of A contains the upper
     373                 :             : !*          triangular part of the matrix A, and the strictly lower
     374                 :             : !*          triangular part of A is not referenced.  If UPLO = 'L', the
     375                 :             : !*          leading N-by-N lower triangular part of A contains the lower
     376                 :             : !*          triangular part of the matrix A, and the strictly upper
     377                 :             : !*          triangular part of A is not referenced.
     378                 :             : !*
     379                 :             : !*          On exit, if INFO = 0, the block diagonal matrix D and the
     380                 :             : !*          multipliers used to obtain the factor U or L from the
     381                 :             : !*          factorization A = U*D*U**T or A = L*D*L**T as computed by
     382                 :             : !*          DSYTRF.
     383                 :             : !*
     384                 :             : !*  LDA     (input) INTEGER
     385                 :             : !*          The leading dimension of the array A.  LDA >= max(1,N).
     386                 :             : !*
     387                 :             : !*  IPIV    (output) INTEGER array, dimension (N)
     388                 :             : !*          Details of the interchanges and the block structure of D, as
     389                 :             : !*          determined by DSYTRF.  If IPIV(k) > 0, then rows and columns
     390                 :             : !*          k and IPIV(k) were interchanged, and D(k,k) is a 1-by-1
     391                 :             : !*          diagonal block.  If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0,
     392                 :             : !*          then rows and columns k-1 and -IPIV(k) were interchanged and
     393                 :             : !*          D(k-1:k,k-1:k) is a 2-by-2 diagonal block.  If UPLO = 'L' and
     394                 :             : !*          IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and
     395                 :             : !*          -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2
     396                 :             : !*          diagonal block.
     397                 :             : !*
     398                 :             : !*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
     399                 :             : !*          On entry, the N-by-NRHS right hand side matrix B.
     400                 :             : !*          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
     401                 :             : !*
     402                 :             : !*  LDB     (input) INTEGER
     403                 :             : !*          The leading dimension of the array B.  LDB >= max(1,N).
     404                 :             : !*
     405                 :             : !*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
     406                 :             : !*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
     407                 :             : !*
     408                 :             : !*  LWORK   (input) INTEGER
     409                 :             : !*          The length of WORK.  LWORK >= 1, and for best performance
     410                 :             : !*          LWORK >= max(1,N*NB), where NB is the optimal blocksize for
     411                 :             : !*          DSYTRF.
     412                 :             : !*
     413                 :             : !*          If LWORK = -1, then a workspace query is assumed; the routine
     414                 :             : !*          only calculates the optimal size of the WORK array, returns
     415                 :             : !*          this value as the first entry of the WORK array, and no error
     416                 :             : !*          message related to LWORK is issued by XERBLA.
     417                 :             : !*
     418                 :             : !*  INFO    (output) INTEGER
     419                 :             : !*          = 0: successful exit
     420                 :             : !*          < 0: if INFO = -i, the i-th argument had an illegal value
     421                 :             : !*          > 0: if INFO = i, D(i,i) is exactly zero.  The factorization
     422                 :             : !*               has been completed, but the block diagonal matrix D is
     423                 :             : !*               exactly singular, so the solution could not be computed.
     424                 :             : !*
     425                 :             : !*  =====================================================================
     426                 :             : 
     427         [ #  # ]:           0 :  if(zDEBUG)then
     428                 :           0 :    write(std_out,*) "(A*X=B) A Matrix:", diisSize + 1,'x',diisSize + 1
     429         [ #  # ]:           0 :    do ii=1,diisSize + 1
     430                 :           0 :      write(std_out,*) workMatrix(1:diisSize + 1,ii)
     431                 :             :    end do
     432                 :             : 
     433                 :           0 :    write(std_out,*) "(A*X=B) B Vector:", diisSize + 1
     434         [ #  # ]:           0 :    do ii=1,diisSize + 1
     435                 :           0 :      write(std_out,*) diisCoeff(ii)
     436                 :             :    end do
     437                 :             :  end if
     438                 :             : 
     439                 :             :  call DSYSV('L', diisSize + 1, 1, workMatrix, &
     440                 :             : & diisSize + 1, ipiv, diisCoeff, diisSize + 1, &
     441                 :           0 : & workArray, (diisSize + 1) ** 2, info)
     442                 :             : 
     443         [ #  # ]:           0 :  if (info /= 0) then
     444                 :           0 :    write(std_out,*) "error solving DIIS matrix", info
     445         [ #  # ]:           0 :    do ii=1,diisSize + 1
     446                 :           0 :      write(std_out,*) workMatrix(1:diisSize + 1,ii)
     447                 :             :    end do
     448                 :             :  end if
     449                 :             : 
     450         [ #  # ]:           0 :  if(zDEBUG)then
     451                 :           0 :    write(std_out,*) "(A*X=B) X Vector:",diisSize+1
     452                 :           0 :    suma=0.0
     453         [ #  # ]:           0 :    do ii=1,diisSize+1
     454                 :           0 :      write(std_out,*) ii,diisCoeff(ii)
     455                 :           0 :      suma=suma+diisCoeff(ii)
     456                 :             :    end do
     457                 :             : 
     458                 :           0 :    suma=suma-diisCoeff(diisSize+1)
     459                 :           0 :    write(std_out,*) 'Sum of coefficients=',suma
     460                 :             :  end if
     461                 :             : 
     462         [ #  # ]:           0 :  ABI_FREE(ipiv)
     463         [ #  # ]:           0 :  ABI_FREE(workArray)
     464         [ #  # ]:           0 :  ABI_FREE(workMatrix)
     465         [ #  # ]:           0 :  ABI_FREE(diisMatrix)
     466                 :             : 
     467                 :             : !write(std_out,*) 'diisrelax 09'
     468                 :             : !##########################################################
     469                 :             : !### 09. Build the new coordinates
     470                 :             : 
     471                 :             : !Build the new coordinates, to do it, we compute a new error e,
     472                 :             : !using the linear coefficients (temporary store it in error) applied
     473                 :             : !on previous gradient: e=H^-1(sum_i c_i.g_i)
     474   [ #  #  #  # ]:           0 :  xcart(:, :) = zero
     475   [ #  #  #  # ]:           0 :  error(:, :, diisSize) = zero
     476         [ #  # ]:           0 :  do ii = 1, diisSize, 1
     477                 :             :    xcart(:, :) = xcart(:, :) +&
     478   [ #  #  #  # ]:           0 : &   xcart_hist(:, :, ii) * diisCoeff(ii)
     479                 :             :    error(:, :, diisSize) = error(:, :, diisSize)+&
     480   [ #  #  #  # ]:           0 : &   fcart_hist(:, :, ii) * diisCoeff(ii)
     481                 :             : 
     482         [ #  # ]:           0 :    if(zDEBUG)then
     483                 :           0 :      write (std_out,*) 'Building new coordinates (ii):',ii
     484                 :           0 :      write (std_out,*) 'diisCoeff(ii)',diisCoeff(ii)
     485                 :           0 :      write (std_out,*) 'xcart_hist(:, :, ii)'
     486         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     487                 :           0 :        write (std_out,*) xcart_hist(:,kk,ii)
     488                 :             :      end do
     489                 :           0 :      write (std_out,*) 'fcart_hist(:, :, ii)'
     490         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     491                 :           0 :        write (std_out,*) fcart_hist(:,kk,ii)
     492                 :             :      end do
     493                 :           0 :      write (std_out,*) 'xcart:'
     494         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     495                 :           0 :        write (std_out,*) xcart(:,kk)
     496                 :             :      end do
     497                 :           0 :      write (std_out,*) 'error:'
     498         [ #  # ]:           0 :      do kk=1,ab_mover%natom
     499                 :           0 :        write (std_out,*) error(:,kk,diisSize)
     500                 :             :      end do
     501                 :             :    end if
     502                 :             : 
     503                 :             :  end do
     504                 :           0 :  ABI_FREE(diisCoeff)
     505                 :             : 
     506         [ #  # ]:           0 :  error_tmp(:)=RESHAPE( error(:,:,diisSize), (/ 3*ab_mover%natom /) )
     507         [ #  # ]:           0 :  xcart_tmp(:)=RESHAPE( xcart(:,:), (/ 3*ab_mover%natom /) )
     508                 :             : 
     509                 :             : !*  BLAS ROUTINE LEVEL 2
     510                 :             : !*  DGEMV  performs one of the matrix-vector operations
     511                 :             : !*
     512                 :             : !*     y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,
     513                 :             : !*
     514                 :             : !*  where alpha and beta are scalars, x and y are vectors and A is an
     515                 :             : !*  m by n matrix.
     516                 :             : 
     517                 :             : !Here we are computing:
     518                 :             : !xcart_tmp(ndim) := -1*hessin(ndim x ndim)*error_tmp(ndim) + 1*xcart_tmp(ndim)
     519                 :             : !
     520                 :             :  call DGEMV('N', ndim, ndim, -one , hessin, &
     521                 :           0 : & ndim, error_tmp, 1, one, xcart_tmp, 1)
     522         [ #  # ]:           0 :  xcart(:,:)=RESHAPE( xcart_tmp(:), (/ 3, ab_mover%natom /) )
     523                 :             : 
     524                 :             : !write(std_out,*) 'diisrelax 10'
     525                 :             : !##########################################################
     526                 :             : !### 10. Update the hessian matrix using a BFGS algorithm.
     527         [ #  # ]:           0 :  if (itime > 1) then
     528                 :             :    call hessupdt(hessin, ab_mover%iatfix, ab_mover%natom, ndim, &
     529                 :             : &   reshape(xcart_hist(:,:,diisSize)  , (/ ndim /)), &
     530                 :             : &   reshape(xcart_hist(:,:,diisSize-1), (/ ndim /)), &
     531                 :             : &   reshape(fcart_hist(:,:,diisSize)  , (/ ndim /)), &
     532   [ #  #  #  #  :           0 : &   reshape(fcart_hist(:,:,diisSize-1), (/ ndim /)))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     533                 :             :  end if
     534                 :             : 
     535         [ #  # ]:           0 :  ABI_FREE(xcart_hist)
     536                 :             : 
     537                 :             : !write(std_out,*) 'diisrelax 11'
     538                 :             : !##########################################################
     539                 :             : !### 11. Update the history with the prediction
     540                 :             : 
     541                 :             : !Increase indexes
     542                 :           0 :  hist%ihist = abihist_findIndex(hist,+1)
     543                 :             : 
     544                 :             : !Compute xred from xcart and rprimd
     545                 :           0 :  call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
     546                 :             : 
     547                 :             : !Fill the history with the variables
     548                 :             : !xred, acell, rprimd, vel
     549                 :           0 :  call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
     550                 :           0 :  ihist_prev = abihist_findIndex(hist,-1)
     551   [ #  #  #  # ]:           0 :  hist%vel(:,:,hist%ihist)=hist%vel(:,:,ihist_prev)
     552                 :             : 
     553                 :             :  if (.false.) write(std_out,*) ntime
     554                 :             : 
     555         [ #  # ]:           0 : end subroutine pred_diisrelax
     556                 :             : !!***
     557                 :             : 
     558                 :             : end module m_pred_diisrelax
     559                 :             : !!***
        

Generated by: LCOV version 2.3-1