LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_xfpack.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.8 % 237 156
Test Date: 2026-09-21 22:40:37 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !!****m* ABINIT/m_xfpack
       2              : !! NAME
       3              : !!  m_xfpack
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 1998-2026 ABINIT group (XG, MJV, DCA, 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_xfpack
      22              : 
      23              :  use defs_basis
      24              :  use m_errors
      25              :  use m_abicore
      26              :  use m_abimover
      27              : 
      28              :  use m_matrix,     only : matr3inv
      29              :  use m_geometry,   only : mkradim, mkrdim, metric, strainsym
      30              :  use m_results_gs , only : results_gs_type
      31              :  use m_bfgs,        only : hessupdt
      32              : 
      33              :  implicit none
      34              : 
      35              :  private
      36              : !!***
      37              : 
      38              :  public :: xfpack_vin2x
      39              :  public :: xfpack_x2vin
      40              :  public :: xfpack_f2vout
      41              :  public :: xfh_recover_new
      42              :  public :: xfh_update
      43              : !!***
      44              : 
      45              : contains
      46              : !!***
      47              : 
      48              : !!****f* ABINIT/xfpack_vin2x
      49              : !! NAME
      50              : !! xfpack_vin2x
      51              : !!
      52              : !! FUNCTION
      53              : !! Old option=2, transfer vin  to xred, acell and rprim
      54              : !!
      55              : !! INPUTS
      56              : !! acell0(3)=reference length scales of primitive translations (bohr), needed for some values of optcell.
      57              : !! natom=number of atoms in cell
      58              : !! ndim=dimension of vin array
      59              : !! nsym=order of group.
      60              : !! rprimd0(3,3)=reference real space primitive translations,
      61              : !!   needed for some values of optcell.
      62              : !! optcell=option for the optimisation of the unit cell. Described in abinit_help.
      63              : !!  Depending on its value, different part of acell and rprim
      64              : !!  are contained in vin.
      65              : !! symrel(3,3,nsym)=symmetry operators in terms of action on primitive translations
      66              : !! ucvol=unit cell volume (bohr^3), needed for some values of optcell.
      67              : !! ucvol0=reference unit cell volume (bohr^3), needed for some values of optcell.
      68              : !!
      69              : !! OUTPUT
      70              : !!  (see side effects)
      71              : !!
      72              : !! SIDE EFFECTS
      73              : !! Input/Output variables
      74              : !! acell(3)=length scales of primitive translations (bohr)
      75              : !! rprim(3,3)=dimensionless real space primitive translations
      76              : !! vin(ndim)=vector that contains xred and some quantity derived
      77              : !!   from acell and rprim, depending on the value of optcell.
      78              : !! xred(3,natom)=reduced dimensionless atomic coordinates
      79              : !!
      80              : !! SOURCE
      81              : 
      82         1009 : subroutine xfpack_vin2x(acell,acell0,natom,ndim,nsym,optcell,&
      83         1009 : & rprim,rprimd0,symrel,ucvol,ucvol0,vin,xred)
      84              : 
      85              : !Arguments ------------------------------------
      86              : !scalars
      87              :  integer,intent(in) :: natom,ndim,nsym,optcell
      88              :  real(dp),intent(in) :: ucvol0
      89              :  real(dp),intent(out) :: ucvol
      90              : !arrays
      91              :  integer,intent(in) :: symrel(3,3,nsym)
      92              :  real(dp),intent(in) :: acell0(3),rprimd0(3,3)
      93              :  real(dp),intent(inout) :: acell(3),rprim(3,3)
      94              :  real(dp),intent(in) :: vin(ndim)
      95              :  real(dp),intent(out) :: xred(3,natom)
      96              : 
      97              : !Local variables-------------------------------
      98              : !scalars
      99              :  integer :: ii,jj,kk
     100              :  real(dp) :: scale
     101              :  character(len=500) :: message
     102              :  logical :: equal=.TRUE.
     103              : !arrays
     104              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3)
     105              :  real(dp) :: rprimd_symm(3,3),scaling(3,3)
     106              : 
     107              : ! *************************************************************************
     108              : 
     109              : !!DEBUG
     110              : !write(ab_out,*) ''
     111              : !write(ab_out,*) 'xfpack_vin2x'
     112              : !write(ab_out,*) 'natom=',natom
     113              : !write(ab_out,*) 'ndim=',ndim
     114              : !write(ab_out,*) 'nsym=',nsym
     115              : !write(ab_out,*) 'optcell=',optcell
     116              : !write(ab_out,*) 'ucvol=',ucvol
     117              : !write(ab_out,*) 'xred='
     118              : !do kk=1,natom
     119              : !write(ab_out,*) xred(:,kk)
     120              : !end do
     121              : !write(ab_out,*) 'VECTOR INPUT (vin) xfpack_vin2x INPUT'
     122              : !do ii=1,ndim,3
     123              : !if (ii+2<=ndim)then
     124              : !write(ab_out,*) ii,vin(ii:ii+2)
     125              : !else
     126              : !write(ab_out,*) ii,vin(ii:ndim)
     127              : !end if
     128              : !end do
     129              : !!DEBUG
     130              : 
     131              : 
     132              : !##########################################################
     133              : !### 1. Test for compatible ndim
     134              : 
     135         1009 :  if(optcell==0 .and. ndim/=3*natom)then
     136              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     137            0 : &   '  When optcell=0, ndim MUST be equal to 3*natom,',ch10,&
     138            0 : &   '  while ndim=',ndim,' and 3*natom=',3*natom,'.'
     139            0 :    ABI_BUG(messagE)
     140              :  end if
     141              : 
     142         1009 :  if( (optcell==1) .and. ndim/=3*natom+1)then
     143              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     144            0 : &   '  When optcell=1 ndim MUST be equal to 3*natom+1,',ch10,&
     145            0 : &   '  while ndim=',ndim,' and 3*natom+1=',3*natom+1,'.'
     146            0 :    ABI_BUG(message)
     147              :  end if
     148              : 
     149         1009 :  if( (optcell==2 .or. optcell==3) .and. ndim/=3*natom+6) then
     150              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     151            0 : &   '  When optcell=2 or 3, ndim MUST be equal to 3*natom+6,',ch10,&
     152            0 : &   '  while ndim=',ndim,' and 3*natom+6=',3*natom+6,'.'
     153            0 :    ABI_BUG(message)
     154              :  end if
     155              : 
     156         1009 :  if( optcell>=4 .and. ndim/=3*natom+3)then
     157              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     158            0 : &   '  When optcell=4,5,6,7,8 or 9, ndim MUST be equal to 3*natom+3,',ch10,&
     159            0 : &   '  while ndim=',ndim,' and 3*natom+3=',3*natom+3,'.'
     160            0 :    ABI_BUG(message)
     161              :  end if
     162              : 
     163              : !##########################################################
     164              : !### 3. option=2, transfer vin  to xred, acell and rprim
     165              : 
     166              : !Get xred, and eventually acell and rprim from vin
     167         3027 :  xred(:,:)=reshape( vin(1:3*natom), (/3,natom/) )
     168              : 
     169         1009 :  if(optcell==1)then
     170              : 
     171              : !  acell(:)=acell0(:)*vin(3*natom+1)/(ucvol0**third)
     172          632 :    acell(:)=acell0(:)*vin(3*natom+1)
     173              : 
     174          851 :  else if (optcell>=2)then
     175              : 
     176          160 :    scaling(:,:)=0.0_dp
     177          160 :    scaling(1,1)=1.0_dp ; scaling(2,2)=1.0_dp ; scaling(3,3)=1.0_dp
     178              : 
     179              :    if(optcell==2 .or. optcell==3)then
     180          129 :      scaling(1,1)=vin(3*natom+1)
     181          129 :      scaling(2,2)=vin(3*natom+2)
     182          129 :      scaling(3,3)=vin(3*natom+3)
     183          129 :      scaling(2,3)=vin(3*natom+4) ; scaling(3,2)=vin(3*natom+4)
     184          129 :      scaling(1,3)=vin(3*natom+5) ; scaling(3,1)=vin(3*natom+5)
     185          129 :      scaling(1,2)=vin(3*natom+6) ; scaling(2,1)=vin(3*natom+6)
     186              :    else if(optcell==4)then
     187            9 :      scaling(1,1)=vin(3*natom+1)
     188            9 :      if (abs(scaling(1,1) - 1.0_dp) <1.E-14) scaling(1,1)=1.0_dp
     189            9 :      scaling(3,1)=vin(3*natom+2)
     190            9 :      if (abs(scaling(3,1)) <1.E-14) scaling(3,1)=0.0_dp
     191            9 :      scaling(2,1)=vin(3*natom+3)
     192            9 :      if (abs(scaling(2,1)) <1.E-14) scaling(2,1)=0.0_dp
     193              :    else if(optcell==5)then
     194            0 :      scaling(2,2)=vin(3*natom+1)
     195            0 :      if (abs(scaling(2,2) - 1.0_dp) <1.E-14) scaling(2,2)=1.0_dp
     196            0 :      scaling(3,2)=vin(3*natom+2)
     197            0 :      if (abs(scaling(3,2)) <1.E-14) scaling(3,2)=0.0_dp
     198            0 :      scaling(1,2)=vin(3*natom+3)
     199            0 :      if (abs(scaling(1,2)) <1.E-14) scaling(1,2)=0.0_dp
     200              :    else if(optcell==6)then
     201            5 :      scaling(3,3)=vin(3*natom+1)
     202            5 :      if (abs(scaling(3,3) - 1.0_dp) <1.E-14) scaling(3,3)=1.0_dp
     203            5 :      scaling(2,3)=vin(3*natom+2)
     204            5 :      if (abs(scaling(2,3)) <1.E-14) scaling(2,3)=0.0_dp
     205            5 :      scaling(1,3)=vin(3*natom+3)
     206            5 :      if (abs(scaling(1,3)) <1.E-14) scaling(1,3)=0.0_dp
     207              :    else if(optcell==7)then
     208           13 :      scaling(2,2)=vin(3*natom+2) ; scaling(3,3)=vin(3*natom+3)
     209           13 :      scaling(2,3)=vin(3*natom+1) ; scaling(3,2)=vin(3*natom+1)
     210              :    else if(optcell==8)then
     211            0 :      scaling(1,1)=vin(3*natom+1) ; scaling(3,3)=vin(3*natom+3)
     212            0 :      scaling(1,3)=vin(3*natom+2) ; scaling(3,1)=vin(3*natom+2)
     213              :    else if(optcell==9)then
     214            4 :      scaling(1,1)=vin(3*natom+1) ; scaling(2,2)=vin(3*natom+2)
     215            4 :      scaling(1,2)=vin(3*natom+3) ; scaling(2,1)=vin(3*natom+3)
     216              :    end if
     217          160 :    if(optcell<=3 .or. optcell>=7)then
     218          584 :      do ii=1,3
     219         1898 :        do jj=1,3
     220         1314 :          rprimd(ii,jj)=0.0_dp
     221         5694 :          do kk=1,3
     222         5256 :            rprimd(ii,jj)=rprimd(ii,jj)+scaling(ii,kk)*rprimd0(kk,jj)
     223              :          end do
     224              :        end do
     225              :      end do
     226              :    ! for optcell=4,5,6, implementing search for all 3 components of the vector to be relaxed according to Eq.10 of J. Chem. Phys.
     227              :    ! 136, 074103 (2012), i.e. search direction given by rprimd0 * stress
     228           14 :    else if(optcell==4)then
     229           36 :      rprimd(:,2) = rprimd0(:,2)
     230           36 :      rprimd(:,3) = rprimd0(:,3)
     231           36 :      rprimd(:,1) = 0.0_dp
     232           36 :      do ii=1,3
     233          117 :        do kk=1,3
     234          108 :           rprimd(ii,1) = rprimd(ii,1) + scaling(kk,1)*rprimd0(ii,kk)
     235              :        end do
     236              :      end do
     237            5 :    else if(optcell==5)then
     238            0 :      rprimd(:,1) = rprimd0(:,1)
     239            0 :      rprimd(:,3) = rprimd0(:,3)
     240            0 :      rprimd(:,2) = 0.0_dp
     241            0 :      do ii=1,3
     242            0 :        do kk=1,3
     243            0 :           rprimd(ii,2) = rprimd(ii,2) + scaling(kk,2)*rprimd0(ii,kk)
     244              :        end do
     245              :      end do
     246              :    else if(optcell==6)then
     247           20 :      rprimd(:,1) = rprimd0(:,1)
     248           20 :      rprimd(:,2) = rprimd0(:,2)
     249           20 :      rprimd(:,3) = 0.0_dp
     250           20 :      do ii=1,3
     251           65 :        do kk=1,3
     252           60 :           rprimd(ii,3) = rprimd(ii,3) + scaling(kk,3)*rprimd0(ii,kk)
     253              :        end do
     254              :      end do
     255              :    end if
     256              : 
     257              : !  Rescale if the volume must be preserved
     258          160 :    if(optcell==3)then
     259           11 :      call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     260           11 :      scale=(ucvol0/ucvol)**third
     261          143 :      rprimd(:,:)=scale*rprimd(:,:)
     262              :    end if
     263          160 :    call strainsym(nsym,rprimd0,rprimd,rprimd_symm,symrel)
     264          640 :    do jj=1,3
     265         2080 :      do ii=1,3
     266              : !      write(ab_out,*) 'DIFF',ii,jj,abs(rprimd0(ii,jj)-rprimd_symm(ii,jj))
     267         1440 :        if (abs(rprimd0(ii,jj)-rprimd_symm(ii,jj))>1.E-14)&
     268         1335 : &       equal=.FALSE.
     269              :      end do
     270              :    end do
     271              : 
     272          160 :    if (equal)then
     273            0 :      acell(:)=acell0(:)
     274              :      rprimd(:,:)=rprimd0(:,:)
     275              :    else
     276              : !    Use a representation based on normalised rprim vectors
     277          160 :      call mkradim(acell,rprim,rprimd_symm)
     278              :    end if
     279              : 
     280              :  end if
     281              : 
     282         1009 : end subroutine xfpack_vin2x
     283              : !!***
     284              : 
     285              : !!****f* ABINIT/xfpack_x2vin
     286              : !! NAME
     287              : !! xfpack_x2vin
     288              : !!
     289              : !! FUNCTION
     290              : !! Old option=1, transfer xred, acell, and rprim to vin
     291              : !!
     292              : !! INPUTS
     293              : !! acell0(3)=reference length scales of primitive translations (bohr), needed for some values of optcell.
     294              : !! natom=number of atoms in cell
     295              : !! ndim=dimension of vin arrays
     296              : !! nsym=order of group.
     297              : !! rprimd0(3,3)=reference real space primitive translations,
     298              : !!   needed for some values of optcell.
     299              : !! optcell=option for the optimisation of the unit cell. Described in abinit_help.
     300              : !!  Depending on its value, different part of acell and rprim
     301              : !!  are contained in vin.
     302              : !! symrel(3,3,nsym)=symmetry operators in terms of action on primitive translations
     303              : !! ucvol=unit cell volume (bohr^3), needed for some values of optcell.
     304              : !! ucvol0=reference unit cell volume (bohr^3), needed for some values of optcell.
     305              : !!
     306              : !! OUTPUT
     307              : !!  (see side effects)
     308              : !!
     309              : !! SIDE EFFECTS
     310              : !! Input/Output variables
     311              : !! acell(3)=length scales of primitive translations (bohr)
     312              : !! rprim(3,3)=dimensionless real space primitive translations
     313              : !! vin(ndim)=vector that contains xred and some quantity derived
     314              : !!   from acell and rprim, depending on the value of optcell.
     315              : !! xred(3,natom)=reduced dimensionless atomic coordinates
     316              : !!
     317              : !! SOURCE
     318              : 
     319         1027 : subroutine xfpack_x2vin(acell,natom,ndim,nsym,optcell,&
     320         1027 :   & rprim,rprimd0,symrel,ucvol,ucvol0,vin,xred)
     321              : 
     322              : !Arguments ------------------------------------
     323              : !scalars
     324              :  integer,intent(in) :: natom,ndim,nsym,optcell
     325              :  real(dp),intent(in) :: ucvol0
     326              :  real(dp),intent(inout) :: ucvol !vz_i
     327              : !arrays
     328              :  integer,intent(in) :: symrel(3,3,nsym)
     329              :  real(dp),intent(in) :: rprimd0(3,3)
     330              :  real(dp),intent(in) :: acell(3),rprim(3,3)
     331              :  real(dp),intent(in) :: xred(3,natom)
     332              :  real(dp),intent(out) :: vin(ndim)
     333              : 
     334              : !Local variables-------------------------------
     335              : !scalars
     336              :  integer :: ii,jj,kk
     337              :  real(dp) :: scale
     338              :  character(len=500) :: message
     339              : !arrays
     340              :  real(dp) :: gmet(3,3),gprimd(3,3),gprimd0(3,3),rmet(3,3),rprimd(3,3)
     341              :  real(dp) :: rprimd_symm(3,3),scaling(3,3)
     342              : 
     343              : ! *************************************************************************
     344              : 
     345              : !!DEBUG
     346              : !write(ab_out,*) ''
     347              : !write(ab_out,*) 'xfpack_x2vin'
     348              : !write(ab_out,*) 'natom=',natom
     349              : !write(ab_out,*) 'ndim=',ndim
     350              : !write(ab_out,*) 'nsym=',nsym
     351              : !write(ab_out,*) 'optcell=',optcell
     352              : !write(ab_out,*) 'ucvol=',ucvol
     353              : !write(ab_out,*) 'xred='
     354              : !do kk=1,natom
     355              : !write(ab_out,*) xred(:,kk)
     356              : !end do
     357              : !write(ab_out,*) 'VECTOR INPUT (vin) xfpack_x2vin INPUT'
     358              : !do ii=1,ndim,3
     359              : !if (ii+2<=ndim)then
     360              : !write(ab_out,*) ii,vin(ii:ii+2)
     361              : !else
     362              : !write(ab_out,*) ii,vin(ii:ndim)
     363              : !end if
     364              : !end do
     365              : !!DEBUG
     366              : 
     367              : 
     368              : !##########################################################
     369              : !### 1. Test for compatible ndim
     370              : 
     371         1027 :  if(optcell==0 .and. ndim/=3*natom)then
     372              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     373            0 : &   '  When optcell=0, ndim MUST be equal to 3*natom,',ch10,&
     374            0 : &   '  while ndim=',ndim,' and 3*natom=',3*natom,'.'
     375            0 :    ABI_BUG(message)
     376              :  end if
     377              : 
     378         1027 :  if( optcell==1 .and. ndim/=3*natom+1)then
     379              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     380            0 : &   '  When optcell=1, ndim MUST be equal to 3*natom+1,',ch10,&
     381            0 : &   '  while ndim=',ndim,' and 3*natom+1=',3*natom+1,'.'
     382            0 :    ABI_BUG(message)
     383              :  end if
     384              : 
     385              :  if( (optcell==2 .or. optcell==3) &
     386         1027 : & .and. ndim/=3*natom+6)then
     387              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     388            0 : &   '  When optcell=2,3,4,5,6, ndim MUST be equal to 3*natom+6,',ch10,&
     389            0 : &   '  while ndim=',ndim,' and 3*natom+6=',3*natom+6,'.'
     390            0 :    ABI_BUG(message)
     391              :  end if
     392              : 
     393         1027 :  if( optcell>=4 .and. ndim/=3*natom+3)then
     394              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     395            0 : &   '  When optcell=4,5,6,7,8 or 9, ndim MUST be equal to 3*natom+3,',ch10,&
     396            0 : &   '  while ndim=',ndim,' and 3*natom+3=',3*natom+3,'.'
     397            0 :    ABI_BUG(message)
     398              :  end if
     399              : 
     400              : !##########################################################
     401              : !### 2. option=1, transfer xred, acell, and rprim to vin
     402              : 
     403              : !Get vin from xred, acell, and rprim
     404         2054 :  vin(1:3*natom)= reshape(xred(:,:), (/3*natom/) )
     405              : 
     406         1027 :  if(optcell/=0)then
     407          318 :    call mkrdim(acell,rprim,rprimd)
     408          318 :    call strainsym(nsym,rprimd0,rprimd,rprimd_symm,symrel)
     409          318 :    call metric(gmet,gprimd,-1,rmet,rprimd_symm,ucvol)
     410              : 
     411          318 :    if(optcell==1)then
     412              : 
     413              : !    vin(3*natom+1)=ucvol**third
     414          158 :      vin(3*natom+1)=(ucvol/ucvol0)**third
     415              : 
     416          160 :    else if(optcell>=2)then
     417              : 
     418              : !    Generates gprimd0
     419          160 :      call matr3inv(rprimd0,gprimd0)
     420          160 :      if (optcell==2 .or. optcell==3 .or. optcell>=7)then
     421          584 :        do ii=1,3
     422         1898 :          do jj=1,3
     423         1314 :            scaling(ii,jj)=0.0_dp
     424         5694 :            do kk=1,3
     425         5256 :              scaling(ii,jj)=scaling(ii,jj)+rprimd_symm(ii,kk)*gprimd0(jj,kk)
     426              :            end do
     427              :          end do
     428              :        end do
     429              : !    Rescale if the volume must be preserved
     430          146 :        if(optcell==3)then
     431           11 :          scale=(ucvol0/ucvol)**third
     432          143 :          scaling(:,:)=scale*scaling(:,:)
     433              :        end if
     434          146 :        if(optcell==2 .or. optcell==3)then
     435          129 :          vin(3*natom+1)=scaling(1,1) ; vin(3*natom+4)=(scaling(2,3)+scaling(3,2))*0.5_dp
     436          129 :          vin(3*natom+2)=scaling(2,2) ; vin(3*natom+5)=(scaling(1,3)+scaling(3,1))*0.5_dp
     437          129 :          vin(3*natom+3)=scaling(3,3) ; vin(3*natom+6)=(scaling(1,2)+scaling(2,1))*0.5_dp
     438           17 :        else if(optcell>=7)then
     439           17 :          vin(3*natom+1)=scaling(1,1)
     440           17 :          vin(3*natom+2)=scaling(2,2)
     441           17 :          vin(3*natom+3)=scaling(3,3)
     442           17 :          if(optcell==7)vin(3*natom+1)=(scaling(2,3)+scaling(3,2))*0.5_dp
     443           17 :          if(optcell==8)vin(3*natom+2)=(scaling(1,3)+scaling(3,1))*0.5_dp
     444           17 :          if(optcell==9)vin(3*natom+3)=(scaling(1,2)+scaling(2,1))*0.5_dp
     445              :        end if
     446              :      end if
     447              : 
     448          160 :      if (optcell==4)then
     449            9 :        scaling(:,:) = 0.0_dp
     450           36 :        do ii=1,3
     451          117 :           do kk=1,3
     452          108 :             scaling(ii,1) = scaling(ii,1) + gprimd0(kk,ii)*rprimd_symm(kk,1)
     453              :           end do
     454              :        end do
     455            9 :        vin(3*natom+1) = scaling(1,1)
     456            9 :        vin(3*natom+2) = scaling(3,1)
     457            9 :        vin(3*natom+3) = scaling(2,1)
     458          151 :      else if (optcell==5)then
     459            0 :        scaling(:,:) = 0.0_dp
     460            0 :        do ii=1,3
     461            0 :           do kk=1,3
     462            0 :             scaling(ii,2) = scaling(ii,2) + gprimd0(kk,ii)*rprimd_symm(kk,2)
     463              :           end do
     464              :        end do
     465            0 :        vin(3*natom+1) = scaling(2,2)
     466            0 :        vin(3*natom+2) = scaling(3,2)
     467            0 :        vin(3*natom+3) = scaling(1,2)
     468          151 :      else if (optcell==6)then
     469            5 :        scaling(:,:) = 0.0_dp
     470           20 :        do ii=1,3
     471           65 :           do kk=1,3
     472           60 :             scaling(ii,3) = scaling(ii,3) + gprimd0(kk,ii)*rprimd_symm(kk,3)
     473              :           end do
     474              :        end do
     475            5 :        vin(3*natom+1) = scaling(3,3)
     476            5 :        vin(3*natom+2) = scaling(2,3)
     477            5 :        vin(3*natom+3) = scaling(1,3)
     478              :      end if
     479              : 
     480              :    end if
     481              : 
     482              :  end if
     483              : 
     484         1027 : end subroutine xfpack_x2vin
     485              : !!***
     486              : 
     487              : !!****f* ABINIT/xfpack_f2vout
     488              : !! NAME
     489              : !! xfpack_f2vout
     490              : !!
     491              : !! FUNCTION
     492              : !! Old option=3, transfer gred and strten to vout
     493              : !!
     494              : !! INPUTS
     495              : !! natom=number of atoms in cell
     496              : !! ndim=dimension of vout arrays
     497              : !! optcell=option for the optimisation of the unit cell. Described in abinit_help.
     498              : !!  Depending on its value, different part of strten
     499              : !!  are contained in vout.
     500              : !! strtarget(6)=target stresses ; they will be subtracted from strten when vout
     501              : !!  is computed.
     502              : !! ucvol=unit cell volume (bohr^3), needed for some values of optcell.
     503              : !!
     504              : !! OUTPUT
     505              : !!  (see side effects)
     506              : !!
     507              : !! SIDE EFFECTS
     508              : !! Input/Output variables
     509              : !! gred(3,natom)=grads of Etot wrt reduced coordinates (hartree)
     510              : !! strten(6)=components of the stress tensor (hartree/bohr^3)
     511              : !! vout(ndim)=vector that contains gred and some quantity derived from
     512              : !!   strten, depending on the value of optcell, and taking care ot strtarget
     513              : !!
     514              : !! SOURCE
     515              : 
     516         1009 : subroutine xfpack_f2vout(gred,natom,ndim,optcell,strtarget,strten,ucvol,vout)
     517              : 
     518              : !Arguments ------------------------------------
     519              : !scalars
     520              :  integer,intent(in) :: natom,ndim,optcell
     521              :  real(dp),intent(in) :: ucvol
     522              : !arrays
     523              :  real(dp),intent(in) :: strtarget(6)
     524              :  real(dp),intent(in) :: gred(3,natom),strten(6)
     525              :  real(dp),intent(out) :: vout(ndim)
     526              : 
     527              : !Local variables-------------------------------
     528              : !scalars
     529              :  real(dp) :: strdiag
     530              :  character(len=500) :: message
     531              : !arrays
     532              :  real(dp) :: dstr(6)
     533              : 
     534              : ! *************************************************************************
     535              : 
     536              : !!DEBUG
     537              : !write(ab_out,*) ''
     538              : !write(ab_out,*) 'xfpack_f2vout'
     539              : !write(ab_out,*) 'natom=',natom
     540              : !write(ab_out,*) 'ndim=',ndim
     541              : !write(ab_out,*) 'optcell=',optcell
     542              : !write(ab_out,*) 'ucvol=',ucvol
     543              : !!DEBUG
     544              : 
     545              : 
     546              : !##########################################################
     547              : !### 1. Test for compatible ndim
     548              : 
     549         1009 :  if(optcell==0 .and. ndim/=3*natom)then
     550              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     551            0 : &   '  When optcell=0, ndim MUST be equal to 3*natom,',ch10,&
     552            0 : &   '  while ndim=',ndim,' and 3*natom=',3*natom,'.'
     553            0 :    ABI_BUG(message)
     554              :  end if
     555              : 
     556         1009 :  if( optcell==1 .and. ndim/=3*natom+1)then
     557              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     558            0 : &   '  When optcell=1, ndim MUST be equal to 3*natom+1,',ch10,&
     559            0 : &   '  while ndim=',ndim,' and 3*natom+1=',3*natom+1,'.'
     560            0 :    ABI_BUG(message)
     561              :  end if
     562              : 
     563              :  if( (optcell==2 .or. optcell==3) &
     564         1009 : & .and. ndim/=3*natom+6)then
     565              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     566            0 : &   '  When optcell=2 or 3, ndim MUST be equal to 3*natom+6,',ch10,&
     567            0 : &   '  while ndim=',ndim,' and 3*natom+6=',3*natom+6,'.'
     568            0 :    ABI_BUG(message)
     569              :  end if
     570              : 
     571         1009 :  if( optcell>=4 .and. ndim/=3*natom+3)then
     572              :    write(message,'(a,a,a,i4,a,i4,a)' )&
     573            0 : &   '  When optcell=4,5,6,7,8 or 9, ndim MUST be equal to 3*natom+3,',ch10,&
     574            0 : &   '  while ndim=',ndim,' and 3*natom+3=',3*natom+3,'.'
     575            0 :    ABI_BUG(message)
     576              :  end if
     577              : !
     578              : !Get vout from gred and strten
     579              : !
     580         2018 :  vout(1:3*natom)= reshape(gred(:,:), (/3*natom/) )
     581         7063 :  dstr(:)=strten(:)-strtarget(:)
     582              : 
     583         1009 :  if(optcell==1)then
     584              : 
     585          158 :    vout(3*natom+1)=( dstr(1)+dstr(2)+dstr(3))*ucvol
     586              : 
     587          851 :  else if(optcell>=2)then
     588              : !  Eventually take away the trace
     589          160 :    strdiag=0.0_dp
     590          160 :    if(optcell==3) strdiag=(dstr(1)+dstr(2)+dstr(3))/3.0_dp
     591              :    if(optcell==2 .or. optcell==3)then
     592          516 :      vout(3*natom+1:3*natom+3)=(dstr(1:3)-strdiag)*ucvol
     593              : !    For non-diagonal derivatives, must take into account
     594              : !    that eps(i,j) AND eps(j,i) are varied at the same time. Thus, derivative
     595              : !    is twice larger
     596          516 :      vout(3*natom+4:3*natom+6)=dstr(4:6)*ucvol*2.0_dp
     597              :    else if(optcell==7 .or. optcell==8 .or. optcell==9)then
     598              : !    Similar to case optcell==2 or optcell==3, but in 2 dimensions.
     599           68 :      vout(3*natom+1:3*natom+3)=dstr(1:3)*ucvol
     600           17 :      vout(3*natom+optcell-6)  =dstr(optcell-3)*ucvol*2.0_dp
     601              :    else if (optcell==4)then
     602            9 :      vout(3*natom+1) = dstr(1)*ucvol
     603            9 :      vout(3*natom+2) = dstr(5)*ucvol
     604            9 :      vout(3*natom+3) = dstr(6)*ucvol
     605              :    else if (optcell==5)then
     606            0 :      vout(3*natom+1) = dstr(2)*ucvol
     607            0 :      vout(3*natom+2) = dstr(4)*ucvol
     608            0 :      vout(3*natom+3) = dstr(6)*ucvol
     609              :    else if (optcell==6)then
     610            5 :      vout(3*natom+1) = dstr(3)*ucvol
     611            5 :      vout(3*natom+2) = dstr(4)*ucvol
     612            5 :      vout(3*natom+3) = dstr(5)*ucvol
     613              :    end if
     614              : 
     615              :  end if
     616              : 
     617         1009 : end subroutine xfpack_f2vout
     618              : !!***
     619              : 
     620              : 
     621              : !!****f* ABINIT/xfh_recover_new
     622              : !! NAME
     623              : !! xfh_recover_new
     624              : !!
     625              : !! FUNCTION
     626              : !! Update the contents of the history xfhist taking values
     627              : !! from xred, acell, rprim, gred_corrected and strten
     628              : !!
     629              : !! INPUTS
     630              : !!
     631              : !! OUTPUT
     632              : !!
     633              : !! SOURCE
     634              : 
     635              : 
     636            7 : subroutine xfh_recover_new(ab_xfh,ab_mover,acell,cycl_main,gred,&
     637            7 : & hessin,ndim,rprim,rprimd0,strten,ucvol,ucvol0,vin,vin_prev,vout,&
     638           14 : & vout_prev,xred)
     639              : 
     640              : !Arguments ------------------------------------
     641              : !scalars
     642              : 
     643              : integer,intent(in) :: ndim
     644              : integer,intent(out) :: cycl_main
     645              : real(dp),intent(inout) :: ucvol,ucvol0
     646              : type(ab_xfh_type),intent(inout) :: ab_xfh
     647              : type(abimover),intent(in) :: ab_mover
     648              : 
     649              : 
     650              : !arrays
     651              : real(dp),intent(inout) :: acell(3)
     652              : real(dp),intent(inout) :: hessin(:,:)
     653              : real(dp),intent(inout) :: xred(3,ab_mover%natom)
     654              : real(dp),intent(inout) :: rprim(3,3)
     655              : real(dp),intent(inout) :: rprimd0(3,3)
     656              : real(dp),intent(inout) :: gred(3,ab_mover%natom)
     657              : real(dp),intent(inout) :: strten(6)
     658              : real(dp),intent(inout) :: vin(:)
     659              : real(dp),intent(inout) :: vin_prev(:)
     660              : real(dp),intent(inout) :: vout(:)
     661              : real(dp),intent(inout) :: vout_prev(:)
     662              : 
     663              : !Local variables-------------------------------
     664              : !scalars
     665              : integer :: ixfh ! kk,jj
     666              : 
     667              : !*********************************************************************
     668              : 
     669            7 :  if(ab_xfh%nxfh/=0)then
     670              : !  Loop over previous time steps
     671            0 :    do ixfh=1,ab_xfh%nxfh
     672              : 
     673              : !    For that time step, get new (x,f) from xfhist
     674            0 :      xred(:,:)     =ab_xfh%xfhist(:,1:ab_mover%natom        ,1,ixfh)
     675            0 :      rprim(1:3,1:3)=ab_xfh%xfhist(:,ab_mover%natom+2:ab_mover%natom+4,1,ixfh)
     676            0 :      acell(:)      =ab_xfh%xfhist(:,ab_mover%natom+1,1,ixfh)
     677            0 :      gred(:,:)     =ab_xfh%xfhist(:,1:ab_mover%natom,2,ixfh)
     678              : !    This use of results_gs is unusual
     679            0 :      strten(1:3)   =ab_xfh%xfhist(:,ab_mover%natom+2,2,ixfh)
     680            0 :      strten(4:6)   =ab_xfh%xfhist(:,ab_mover%natom+3,2,ixfh)
     681              : 
     682              : !    !DEBUG
     683              : !    write (ab_out,*) '---READED FROM XFHIST---'
     684              : 
     685              : !    write (ab_out,*) 'XRED'
     686              : !    do kk=1,ab_mover%natom
     687              : !    write (ab_out,*) xred(:,kk)
     688              : !    end do
     689              : !    write (ab_out,*) 'FRED'
     690              : !    do kk=1,ab_mover%natom
     691              : !    write (ab_out,*) gred(:,kk)
     692              : !    end do
     693              : !    write(ab_out,*) 'RPRIM'
     694              : !    do kk=1,3
     695              : !    write(ab_out,*) rprim(:,kk)
     696              : !    end do
     697              : !    write(ab_out,*) 'ACELL'
     698              : !    write(ab_out,*) acell(:)
     699              : !    !DEBUG
     700              : 
     701              : !    Transfer it in vin, vout
     702              :      call xfpack_x2vin(acell,ab_mover%natom,&
     703              : &     ndim,ab_mover%nsym,ab_mover%optcell,rprim,rprimd0,&
     704            0 : &     ab_mover%symrel,ucvol,ucvol0,vin,xred)
     705              :      call xfpack_f2vout(gred,ab_mover%natom,&
     706              : &     ndim,ab_mover%optcell,ab_mover%strtarget,strten,&
     707            0 : &     ucvol,vout)
     708              : !    Get old time step, if any, and update inverse hessian
     709            0 :      if(ixfh/=1)then
     710            0 :        xred(:,:)     =ab_xfh%xfhist(:,1:ab_mover%natom,1,ixfh-1)
     711              :        rprim(1:3,1:3)=&
     712            0 : &       ab_xfh%xfhist(:,ab_mover%natom+2:ab_mover%natom+4,1,ixfh-1)
     713            0 :        acell(:)=ab_xfh%xfhist(:,ab_mover%natom+1,1,ixfh-1)
     714            0 :        gred(:,:)=ab_xfh%xfhist(:,1:ab_mover%natom,2,ixfh-1)
     715              : !      This use of results_gs is unusual
     716            0 :        strten(1:3)=ab_xfh%xfhist(:,ab_mover%natom+2,2,ixfh-1)
     717            0 :        strten(4:6)=ab_xfh%xfhist(:,ab_mover%natom+3,2,ixfh-1)
     718              : !      Tranfer it in vin_prev, vout_prev
     719              :        call xfpack_x2vin(acell,ab_mover%natom,&
     720              : &       ndim,ab_mover%nsym,ab_mover%optcell,rprim,rprimd0,&
     721            0 : &       ab_mover%symrel,ucvol,ucvol0,vin_prev,xred)
     722              :        call xfpack_f2vout(gred,ab_mover%natom,&
     723              : &       ndim,ab_mover%optcell,ab_mover%strtarget,strten,&
     724            0 : &       ucvol,vout_prev)
     725              : 
     726              : !      write(ab_out,*) 'Hessian matrix before update',ndim,'x',ndim
     727              : !      write(ab_out,*) 'ixfh=',ixfh
     728              : !      do kk=1,ndim
     729              : !      do jj=1,ndim,3
     730              : !      if (jj+2<=ndim)then
     731              : !      write(ab_out,*) jj,hessin(jj:jj+2,kk)
     732              : !      else
     733              : !      write(ab_out,*) jj,hessin(jj:ndim,kk)
     734              : !      end if
     735              : !      end do
     736              : !      end do
     737              : 
     738              :        call hessupdt(hessin,ab_mover%iatfix,ab_mover%natom,ndim,&
     739            0 : &       vin,vin_prev,vout,vout_prev)
     740              : 
     741              : !      !DEBUG
     742              : !      write(ab_out,*) 'Hessian matrix after update',ndim,'x',ndim
     743              : !      do kk=1,ndim
     744              : !      do jj=1,ndim,3
     745              : !      if (jj+2<=ndim)then
     746              : !      write(ab_out,*) jj,hessin(jj:jj+2,kk)
     747              : !      else
     748              : !      write(ab_out,*) jj,hessin(jj:ndim,kk)
     749              : !      end if
     750              : !      end do
     751              : !      end do
     752              : !      !DEBUG
     753              : 
     754              :      end if !if(ab_xfh%nxfh/=0)
     755              :    end do ! End loop over previous time steps
     756              : 
     757              : !  The hessian has been generated,
     758              : !  as well as the latest vin and vout
     759              : !  so will cycle the main loop
     760            0 :    cycl_main=1
     761              :  end if
     762              : 
     763            7 : end subroutine xfh_recover_new
     764              : !!***
     765              : 
     766              : !!****f* ABINIT/xfh_update
     767              : !! NAME
     768              : !! xfh_update
     769              : !!
     770              : !! FUNCTION
     771              : !! Update the contents of the history xfhist taking values
     772              : !! from xred, acell, rprim, gred_corrected and strten
     773              : !!
     774              : !! INPUTS
     775              : !!
     776              : !! OUTPUT
     777              : !!
     778              : !! SOURCE
     779              : 
     780         1158 : subroutine xfh_update(ab_xfh,acell,gred_corrected,natom,rprim,strten,xred)
     781              : 
     782              : !Arguments ------------------------------------
     783              : !scalars
     784              : type(ab_xfh_type),intent(inout) :: ab_xfh
     785              : integer,intent(in) :: natom
     786              : 
     787              : !arrays
     788              : real(dp),intent(in) :: acell(3)
     789              : real(dp),intent(in) :: xred(3,natom)
     790              : real(dp),intent(in) :: rprim(3,3)
     791              : real(dp),intent(in) :: gred_corrected(3,natom)
     792              : real(dp),intent(in) :: strten(6)
     793              : 
     794              : !Local variables-------------------------------
     795              : !scalars
     796              : !integer :: kk
     797              : 
     798              : !*********************************************************************
     799              : 
     800              : !DEBUG
     801              : !write (ab_out,*) '---WROTE TO XFHIST---'
     802              : 
     803              : !write (ab_out,*) 'XRED'
     804              : !do kk=1,natom
     805              : !write (ab_out,*) xred(:,kk)
     806              : !end do
     807              : !write (ab_out,*) 'FRED'
     808              : !do kk=1,natom
     809              : !write (ab_out,*) gred_corrected(:,kk)
     810              : !end do
     811              : !write(ab_out,*) 'RPRIM'
     812              : !do kk=1,3
     813              : !write(ab_out,*) rprim(:,kk)
     814              : !end do
     815              : !write(ab_out,*) 'ACELL'
     816              : !write(ab_out,*) acell(:)
     817              : !DEBUG
     818              : 
     819         1158 :  ab_xfh%nxfh=ab_xfh%nxfh+1
     820              : 
     821        11986 :  ab_xfh%xfhist(:,1:natom,1,ab_xfh%nxfh)=xred(:,:)
     822         4632 :  ab_xfh%xfhist(:,natom+1,1,ab_xfh%nxfh)=acell(:)
     823        15054 :  ab_xfh%xfhist(:,natom+2:natom+4,1,ab_xfh%nxfh)=rprim(:,:)
     824        11986 :  ab_xfh%xfhist(:,1:natom,2,ab_xfh%nxfh)=gred_corrected(:,:)
     825         4632 :  ab_xfh%xfhist(:,natom+2,2,ab_xfh%nxfh)=strten(1:3)
     826         4632 :  ab_xfh%xfhist(:,natom+3,2,ab_xfh%nxfh)=strten(4:6)
     827              : 
     828         1158 : end subroutine xfh_update
     829              : !!***
     830              : 
     831              : end module m_xfpack
     832              : !!***
        

Generated by: LCOV version 2.3-1