LCOV - code coverage report
Current view: top level - src/44_abitools - m_macroave.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 59.3 % 140 83
Test Date: 2026-09-20 18:56:22 Functions: 75.0 % 8 6

            Line data    Source code
       1              : !!****m* ABINIT/m_macroave
       2              : !! NAME
       3              : !! m_macroave
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 1997-2003 J.Soler, P. Ordejon, J. Junquera
       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_macroave
      22              : 
      23              :  implicit none
      24              : 
      25              : ! private
      26              : 
      27              :  public :: POLINT
      28              : !!***
      29              : 
      30              : contains
      31              : !!***
      32              : 
      33            0 : subroutine iorho( task, fname, cell, mesh, nsm, maxp, nspin, f, found )
      34              : 
      35              : ! *********************************************************************
      36              : ! Saves/recovers the electron density at the mesh points.
      37              : ! This simplified version reads only files written in serial mode.
      38              : 
      39              : ! Writen by J.Soler July 1997.
      40              : ! Copyright (C) 1997-2003 J.Soler, P. Ordejon, J. Junquera
      41              : ! This file is distributed under the terms of the
      42              : ! GNU General Public License, see ~abinit/COPYING
      43              : ! or http://www.gnu.org/copyleft/gpl.txt .
      44              : 
      45              : ! *************************** INPUT **********************************
      46              : ! character*(*) task      : 'read'/'READ' or 'write'/'WRITE'
      47              : ! character*(*) fname     : File name for input or output
      48              : ! integer nsm             : Number of sub-mesh points per mesh point
      49              : !                           (not used in this version)
      50              : ! integer maxp            : First dimension of array rho
      51              : ! integer nspin           : Second dimension of array rho
      52              : ! ************************** OUTPUT **********************************
      53              : ! integer maxp            : Required first dimension of array rho,
      54              : !                           equal to mesh(1)*mesh(2)*mesh(3)
      55              : !                           Set only when task='read' and required
      56              : !                           value is larger than input value
      57              : ! integer nspin           : Number of spin polarizations (1 or 2)
      58              : ! logical found           : Were data found? (only when task='read')
      59              : ! ******************** INPUT or OUTPUT (depending on task) ***********
      60              : ! real*8  cell(3,3)       : Lattice vectors
      61              : ! integer mesh(3)         : Number of mesh divisions of each
      62              : !                           lattice vector
      63              : ! real    f(maxp,nspin)   : Electron density
      64              : !                           Notice single precision in this version
      65              : ! *************************** UNITS ***********************************
      66              : ! Units should be consistent between task='read' and 'write'
      67              : ! ******************** BEHAVIOUR **************************************
      68              : ! If task='read', and the values of maxp or nspin on input are less than
      69              : ! those required to copy the array f from the file, then the required
      70              : ! values of maxp and nspin are returned on output, but f is not read.
      71              : ! *********************************************************************
      72              : 
      73              : ! Arguments
      74              :       character*(*)     fname, task
      75              :       integer           maxp, mesh(3), nspin, nsm
      76              :       real              f(maxp,nspin)
      77              :       real(kind=kind(0.0d0)) cell(3,3)
      78              :       logical           found
      79              : 
      80              : ! Internal variables and arrays
      81              :       character(len=11) :: fform
      82              :       integer   i2, i3, ind, ip, is, np, ns
      83              : 
      84              :       if(.false.)write(11,*)nsm
      85              :       if(.false.)write(11,*)task
      86              : 
      87              : ! Fix whether formatted or unformatted files will be used
      88            0 :       fform = 'unformatted'
      89              : 
      90              : ! Look for data file
      91            0 :       inquire( file=fname, exist=found )
      92            0 :       if (.not.found) return
      93              : 
      94              : ! Read unit cell vectors, number of mesh points and spin components
      95            0 :       open( unit=1, file=fname, status='old', form=fform )
      96            0 :       if (fform == 'formatted') then
      97            0 :         read(1,*) cell
      98            0 :         read(1,*) mesh, ns
      99              :       else
     100            0 :         read(1,*) cell
     101            0 :         read(1,*) mesh, ns
     102              :       endif
     103              : 
     104              : ! Read density (only if array f is large enough)
     105            0 :       np = mesh(1) * mesh(2) * mesh(3)
     106            0 :       if (ns>nspin .or. np>maxp) then
     107            0 :         maxp = np
     108              :       else
     109            0 :         if (fform == 'formatted') then
     110              :           ind = 0
     111            0 :           do is = 1,ns
     112            0 :             do i3 = 1,mesh(3)
     113            0 :               do i2 = 1,mesh(2)
     114            0 :                 read(1,*) (f(ind+ip,is),ip=1,mesh(1))
     115            0 :                 ind = ind + mesh(1)
     116              :               enddo
     117              :             enddo
     118              :           enddo
     119              :         else
     120              :           ind = 0
     121            0 :           do is = 1,ns
     122            0 :             do i3 = 1,mesh(3)
     123            0 :               do i2 = 1,mesh(2)
     124            0 :                 read(1) (f(ind+ip,is),ip=1,mesh(1))
     125            0 :                 ind = ind + mesh(1)
     126              :               enddo
     127              :             enddo
     128              :           enddo
     129              :         endif
     130              :       endif
     131            0 :       close(1)
     132            0 :       nspin = ns
     133              : end SUBROUTINE iorho
     134              : !!***
     135              : 
     136            4 : SUBROUTINE FOUR1(DATA,NN,ISIGN)
     137              : !**********************************************************************
     138              : ! Discrete Fourier transform.
     139              : !**********************************************************************
     140              : ! Input:
     141              : !   real*8  DATA(2*NN) : Function to be Fourier transformed
     142              : !   integer NN       : Number of points. Must be a power of 2
     143              : !   integer ISIGN    : ISIG=+1/-1 => Direct/inverse transform
     144              : ! Output:
     145              : !   real*8  DATA(2*NN) : Fourier transformed function
     146              : !**********************************************************************
     147              :       INTEGER          :: NN, ISIGN
     148              :       real(kind=kind(0.0d0)) :: DATA(2*NN)
     149              : 
     150              :       INTEGER          :: I, ISTEP, J, M, MMAX, N
     151              :       real(kind=kind(0.0d0)) :: TEMPI, TEMPR, THETA, WI, WPI, WPR, WR, WTEMP
     152              :       DOUBLE PRECISION, PARAMETER :: TWOPI=6.28318530717959D0,&
     153              :      &  HALF=0.5D0, ONE=1.D0, TWO=2.D0, ZERO=0.D0
     154              : 
     155            4 :       N=2*NN
     156            4 :       J=1
     157              : 
     158            4 :       DO I=1,N,2
     159        16384 :         IF(J>I)THEN
     160         8064 :           TEMPR=DATA(J)
     161         8064 :           TEMPI=DATA(J+1)
     162         8064 :           DATA(J)=DATA(I)
     163         8064 :           DATA(J+1)=DATA(I+1)
     164         8064 :           DATA(I)=TEMPR
     165         8064 :           DATA(I+1)=TEMPI
     166              :         ENDIF
     167        16384 :         M=N/2
     168        16380 :         DO ! until following condition is met
     169        32764 :           IF ((M<2).OR.(J<=M)) EXIT
     170        16380 :           J=J-M
     171        16380 :           M=M/2
     172              :         END DO
     173        16384 :         J=J+M
     174              :       END DO ! I
     175              :       MMAX=2
     176              :       DO ! until following condition is met
     177           52 :         IF (N<=MMAX) EXIT
     178           48 :         ISTEP=2*MMAX
     179           48 :         THETA=TWOPI/(ISIGN*MMAX)
     180           48 :         WPR=(-TWO)*SIN(HALF*THETA)**2
     181           48 :         WPI=SIN(THETA)
     182           48 :         WR=ONE
     183           48 :         WI=ZERO
     184           48 :         DO M=1,MMAX,2
     185        16380 :           DO I=M,N,ISTEP
     186        98304 :             J=I+MMAX
     187        98304 :             TEMPR=WR*DATA(J)-WI*DATA(J+1)
     188        98304 :             TEMPI=WR*DATA(J+1)+WI*DATA(J)
     189        98304 :             DATA(J)=DATA(I)-TEMPR
     190        98304 :             DATA(J+1)=DATA(I+1)-TEMPI
     191        98304 :             DATA(I)=DATA(I)+TEMPR
     192        98304 :             DATA(I+1)=DATA(I+1)+TEMPI
     193              :           END DO ! I
     194        16380 :           WTEMP=WR
     195        16380 :           WR=WR*WPR-WI*WPI+WR
     196        16380 :           WI=WI*WPR+WTEMP*WPI+WI
     197              :         END DO ! M
     198            4 :         MMAX=ISTEP
     199              :       END DO ! until (N<=MMAX)
     200              : 
     201            4 : END SUBROUTINE FOUR1
     202              : !!***
     203              : 
     204            0 : SUBROUTINE POLINT(XA,YA,N,X,Y,DY)
     205              : !*****************************************************************
     206              : ! Polinomic interpolation.
     207              : ! D. Sanchez-Portal, Oct. 1996
     208              : !*****************************************************************
     209              : ! Input:
     210              : !   real*8  XA(N) : x values of the function y(x) to interpolate
     211              : !   real*8  YA(N) : y values of the function y(x) to interpolate
     212              : !   integer N     : Number of data points
     213              : !   real*8  X     : x value at which the interpolation is desired
     214              : ! Output:
     215              : !   real*8  Y     : interpolated value of y(x) at X
     216              : !   real*8  DY    : accuracy estimate
     217              : !*****************************************************************
     218              :       INTEGER          :: N
     219              :       real(kind=kind(0.0d0)) :: XA(N),YA(N), X, Y, DY
     220              : 
     221              :       INTEGER          :: I, M, NS
     222            0 :       real(kind=kind(0.0d0)) :: C(N), D(N), DEN, DIF, DIFT, HO, HP, W
     223              :       DOUBLE PRECISION, PARAMETER :: ZERO=0.D0
     224              : 
     225            0 :       NS=1
     226            0 :       DIF=ABS(X-XA(1))
     227            0 :       DO I=1,N
     228            0 :         DIFT=ABS(X-XA(I))
     229            0 :         IF (DIFT<DIF) THEN
     230            0 :           NS=I
     231            0 :           DIF=DIFT
     232              :         ENDIF
     233            0 :         C(I)=YA(I)
     234            0 :         D(I)=YA(I)
     235              :       END DO ! I
     236            0 :       Y=YA(NS)
     237            0 :       NS=NS-1
     238            0 :       DO M=1,N-1
     239            0 :         DO I=1,N-M
     240            0 :           HO=XA(I)-X
     241            0 :           HP=XA(I+M)-X
     242            0 :           W=C(I+1)-D(I)
     243            0 :           DEN=HO-HP
     244            0 :           IF (DEN==ZERO) STOP 'polint: ERROR. Two XAs are equal'
     245            0 :           DEN=W/DEN
     246            0 :           D(I)=HP*DEN
     247            0 :           C(I)=HO*DEN
     248              :         END DO ! I
     249            0 :         IF (2*NS<N-M) THEN
     250            0 :           DY=C(NS+1)
     251              :         ELSE
     252            0 :           DY=D(NS)
     253            0 :           NS=NS-1
     254              :         ENDIF
     255            0 :         Y=Y+DY
     256              :       END DO ! M
     257              : 
     258            0 : END SUBROUTINE POLINT
     259              : 
     260            3 : SUBROUTINE MACROAV_SPLINE(DX,Y,N,YP1,YPN,Y2)
     261              : !***********************************************************
     262              : ! Cubic Spline Interpolation.
     263              : ! D. Sanchez-Portal, Oct. 1996.
     264              : ! Input:
     265              : !   real*8  DX   : x interval between data points
     266              : !   real*8  Y(N) : value of y(x) at data points
     267              : !   integer N    : number of data points
     268              : !   real*8  YP1  : value of dy/dx at X1 (first point)
     269              : !   real*8  YPN  : value of dy/dx at XN (last point)
     270              : ! Output:
     271              : !   real*8  Y2(N): array to be used by routine MACROAV_SPLINT
     272              : ! Behavior:
     273              : ! - If YP1 or YPN are larger than 1E30, the natural spline
     274              : !   condition (d2y/dx2=0) at the corresponding edge point.
     275              : !************************************************************
     276              :       INTEGER          :: N
     277              :       real(kind=kind(0.0d0)) :: DX, Y(N), YP1, YPN, Y2(N)
     278              : 
     279              :       INTEGER          :: I, K
     280            6 :       real(kind=kind(0.0d0)) :: QN, P, SIG, U(N), UN
     281              :       DOUBLE PRECISION, PARAMETER :: YPMAX=0.99D30, &
     282              :      &  HALF=0.5D0, ONE=1.D0, THREE=3.D0, TWO=2.D0, ZERO=0.D0
     283              : 
     284            3 :       IF (YP1>YPMAX) THEN
     285            0 :         Y2(1)=ZERO
     286            0 :         U(1)=ZERO
     287              :       ELSE
     288            3 :         Y2(1)=-HALF
     289            3 :         U(1)=(THREE/DX)*((Y(2)-Y(1))/DX-YP1)
     290              :       ENDIF
     291          160 :       DO I=2,N-1
     292          157 :         SIG=HALF
     293          157 :         P=SIG*Y2(I-1)+TWO
     294          157 :         Y2(I)=(SIG-ONE)/P
     295              :         U(I)=(THREE*( Y(I+1)+Y(I-1)-TWO*Y(I) )/(DX*DX)&
     296          160 :      &       -SIG*U(I-1))/P
     297              :       END DO ! I
     298            3 :       IF (YPN>YPMAX) THEN
     299              :         QN=ZERO
     300              :         UN=ZERO
     301              :       ELSE
     302            3 :         QN=HALF
     303            3 :         UN=(THREE/DX)*(YPN-(Y(N)-Y(N-1))/DX)
     304              :       ENDIF
     305            3 :       Y2(N)=(UN-QN*U(N-1))/(QN*Y2(N-1)+ONE)
     306          163 :       DO K=N-1,1,-1
     307          163 :         Y2(K)=Y2(K)*Y2(K+1)+U(K)
     308              :       END DO ! K
     309              : 
     310            3 : END SUBROUTINE MACROAV_SPLINE
     311              : 
     312              : 
     313        12288 : SUBROUTINE MACROAV_SPLINT(DX,YA,Y2A,N,X,Y,DYDX)
     314              : !***************************************************************
     315              : ! Cubic Spline Interpolation.
     316              : ! D. Sanchez-Portal, Oct. 1996.
     317              : ! Input:
     318              : !   real*8  DX    : x interval between data points
     319              : !   real*8  YA(N) : value of y(x) at data points
     320              : !   real*8  Y2A(N): array returned by routine MACROAV_SPLINE
     321              : !   integer N     : number of data points
     322              : !   real*8  X     : point at which interpolation is desired
     323              : !   real*8  Y     : interpolated value of y(x) at point X
     324              : !   real*8  DYDX  : interpolated value of dy/dx at point X
     325              : !***************************************************************
     326              :       INTEGER          :: N
     327              :       real(kind=kind(0.0d0)) :: DX, YA(N), Y2A(N), X, Y, DYDX
     328              : 
     329              :       INTEGER          :: NHI, NLO
     330              :       real(kind=kind(0.0d0)) :: A, B
     331              :       DOUBLE PRECISION, PARAMETER ::&
     332              :      &    ONE=1.D0, THREE=3.D0, SIX=6.D0, ZERO=0.D0
     333              : 
     334        12288 :       IF (DX==ZERO) STOP 'splint: ERROR: DX=0'
     335        12288 :       NLO=INT(X/DX)+1
     336        12288 :       NHI=NLO+1
     337        12288 :       A=NHI-X/DX-1
     338        12288 :       B=ONE-A
     339              :       Y=A*YA(NLO)+B*YA(NHI)+&
     340        12288 :      &  ((A**3-A)*Y2A(NLO)+(B**3-B)*Y2A(NHI))*(DX**2)/SIX
     341              :       DYDX=(YA(NHI)-YA(NLO))/DX+&
     342              :      &     (-((THREE*(A**2)-ONE)*Y2A(NLO))+&
     343        12288 :      &     (THREE*(B**2)-ONE)*Y2A(NHI))*DX/SIX
     344              : 
     345        12288 : END SUBROUTINE MACROAV_SPLINT
     346              : 
     347              : ! Copyright (C) 1999-2003 (P. Ordejon, J. Junquera)
     348              : ! This file is distributed under the terms of the
     349              : ! GNU General Public License, see ~abinit/COPYING
     350              : ! or http://www.gnu.org/copyleft/gpl.txt .
     351              : 
     352            4 : real(kind=kind(0.0d0)) FUNCTION SURPLA( C )
     353              : 
     354              : !  CALCULATES THE SRFACE OF THE UNIT CELL NORMAL TO THE INTERFACE
     355              : 
     356              :       real(kind=kind(0.0d0)) C(3,3)
     357              :       SURPLA = ( C(2,1)*C(3,2) - C(3,1)*C(2,2) ) **2 +&
     358              :      &         ( C(3,1)*C(1,2) - C(1,1)*C(3,2) ) **2 +&
     359            4 :      &         ( C(1,1)*C(2,2) - C(2,1)*C(1,2) ) **2
     360            4 :       SURPLA = SQRT( ABS( SURPLA ) )
     361            4 : END FUNCTION SURPLA
     362              : 
     363            5 : subroutine thetaft(n,L,lav,ft)
     364              : 
     365              : ! Copyright (C) 1999-2003 (P. Ordejon, J. Junquera)
     366              : ! This file is distributed under the terms of the
     367              : ! GNU General Public License, see ~abinit/COPYING
     368              : ! or http://www.gnu.org/copyleft/gpl.txt .
     369              : 
     370              : !
     371              : ! Calculates the Fourier coefficients of the convoluting function
     372              : !    w(x) = (1/lav) theta(lav/2 - abs(x))
     373              : ! asuming it is periodic with period L:
     374              : !
     375              : !       |                                          |
     376              : !  1/lav|__________                      __________|
     377              : !       |          |                     |         |
     378              : !       |__________|_____________________|_________|___
     379              : !       0         lav/2               L-lav/2     L
     380              : !
     381              :         integer n,j
     382              :         real(kind=kind(0.0d0)) :: L,lav
     383              :         real(kind=kind(0.0d0)) :: ft(2*n)
     384              :         real(kind=kind(0.0d0)) :: pi
     385              : 
     386            5 :         pi=4.0d0*datan(1.0d0)
     387              : 
     388            5 :         ft(1)=n/L
     389            5 :         ft(2)=0.0
     390              : 
     391        10245 :         do j=2,n/2+1
     392              :           ft(2*(j-1)+1) = (n/(pi*lav*(j-1)/2.))*&
     393              :      &                    sin(pi*lav*(j-1)/2./L)*&
     394              :      &                    cos(pi*(L-lav/2.)*(j-1)/L)*&
     395        10240 :      &                    cos(pi*L*(j-1)/L)
     396              :           ft(2*(j-1)+2) = (n/(pi*lav*(j-1)/2.))*&
     397              :      &                    sin(pi*lav*(j-1)/2./L)*&
     398              :      &                    cos(pi*(L-lav/2.)*(j-1)/L)*&
     399        10245 :      &                    sin(pi*L*(j-1)/L)
     400              :         enddo
     401              : 
     402        10240 :         do j=n/2+2,n
     403              :           ft(2*(j-1)+1) = (n/(pi*lav*(-n+j-1)/2.))*&
     404              :      &                    sin(pi*lav*(-n+j-1)/2./L)*&
     405              :      &                    cos(pi*(L-lav/2.)*(-n+j-1)/L)*&
     406        10235 :      &                    cos(pi*L*(-n+j-1)/L)
     407              :           ft(2*(j-1)+2) = (n/(pi*lav*(-n+j-1)/2.))*&
     408              :      &                    sin(pi*lav*(-n+j-1)/2./L)*&
     409              :      &                    cos(pi*(L-lav/2.)*(-n+j-1)/L)*&
     410        10240 :      &                    sin(pi*L*(-n+j-1)/L)
     411              :         enddo
     412              : 
     413              : 
     414            5 :         return
     415              : end subroutine thetaft
     416              : 
     417            4 : DOUBLE PRECISION FUNCTION VOLCEL( C )
     418              : 
     419              : ! Copyright (C) 1999-2003 (P. Ordejon, J. Junquera)
     420              : ! This file is distributed under the terms of the
     421              : ! GNU General Public License, see ~abinit/COPYING
     422              : ! or http://www.gnu.org/copyleft/gpl.txt .
     423              : 
     424              : !  CALCULATES THE VOLUME OF THE UNIT CELL
     425              :       DOUBLE PRECISION C(3,3)
     426              :       VOLCEL = ( C(2,1)*C(3,2) - C(3,1)*C(2,2) ) * C(1,3) +&
     427              :      &         ( C(3,1)*C(1,2) - C(1,1)*C(3,2) ) * C(2,3) +&
     428            4 :      &         ( C(1,1)*C(2,2) - C(2,1)*C(1,2) ) * C(3,3)
     429            4 :       VOLCEL = ABS( VOLCEL )
     430            4 : END FUNCTION VOLCEL
     431              : 
     432              : end module m_macroave
     433              : !!***
        

Generated by: LCOV version 2.3-1