MsSpec-DFM/New_libraries/DFM_library/UTILITIES_LIBRARY/transforms.f90

168 lines
6.2 KiB
Fortran
Raw Normal View History

2022-02-02 16:19:10 +01:00
!
!=======================================================================
!
MODULE TRANSFORMS
!
USE ACCURACY_REAL
!
CONTAINS
!
!
!=======================================================================
!
SUBROUTINE KK(TR,NS,X,U_INP,UR_INF,U_OUT)
!
! This subroutine computes the Kramers-Kronig transform
!
! U_OUT(X) = KK( I_INP(X) )
!
! with U_INP(X) = UR(X)/UI(X)
! U_OUT(X) = UI(X)/UR(X)
!
! The convention here is that UR(X) is an even function of X and that
! UI(X) is an odd function of X
!
! In this case, we have the Kramers-Kronig relations:
!
! _ _
! | / + inf |
! 2 | | X' UI(X') - X UI(X) |
! UR(X) = ---- P | | ------------------- dX' | + UR(+ inf)
! pi | | X'^2 - X^2 |
! |_ / 0 _|
!
!
! _ _
! | / + inf |
! 2X | | UR(X') - UR(X) |
! UI(X) = - ---- P | | -------------------- dX' |
! pi | | X'^2 - X^2 |
! |_ / 0 _|
!
!
! where the Cauchy' principal part P[ ] can be removed
! as the integrand is no longer singular at X' = X
!
! Input parameters:
!
! * TR : type of transformation
! TR = 'R2I' --> UI = KK(UR)
! TR = 'I2R' --> UR = KK(UI)
! * NS : size of arrays of X, UR and UI
! * X : argument array of UR/UI
! * U_INP : input array
! * UR_INF : value of UR(X) for X --> + inf
!
! Output variables :
!
! * U_OUT : output array
!
!
!
! Author : D. Sébilleau
!
! Last modified : 4 Jun 2020
!
!
USE DIMENSION_CODE, ONLY : NSIZE
USE REAL_NUMBERS, ONLY : ZERO,ONE,TWO,HALF
USE PI_ETC, ONLY : PI
USE INTEGRATION, ONLY : INTEGR_L
!
IMPLICIT NONE
!
REAL (WP) :: X(NS),U_INP(NS),U_OUT(NS)
REAL (WP) :: UR_INF
REAL (WP) :: ADD,COEF,H
REAL (WP) :: I1,C,R1,R2
REAL (WP) :: F0(NSIZE),G1(NSIZE)
!
INTEGER :: NS
INTEGER :: J,ID,NSIZE1,K
INTEGER :: LOGF
!
CHARACTER (LEN = 3) :: TR
!
LOGF=6 !
!
ID=0 !
!
! Integration bound
!
NSIZE1=NS !
!
! Checking for the dimensioning
!
IF(NS > NSIZE) THEN !
WRITE(LOGF,10) !
STOP !
ENDIF !
!
H=X(2)-X(1) ! step
!
! Initialization
!
DO J=1,NS !
IF(TR == 'R2I') THEN !
F0(J)=U_INP(J) !
ELSE IF(TR == 'I2R') THEN !
F0(J)=X(J)*U_INP(J) !
END IF !
G1(J)=ZERO !
END DO !
!
! Case-dependent sign
!
IF(TR == 'R2I') THEN !
COEF=+TWO/PI !
ADD=ZERO !
ELSE IF(TR == 'I2R') THEN !
COEF=-TWO/PI !
ADD=UR_INF !
END IF !
!
! Loop over omega
!
DO J=1,NS !
!
IF(TR == 'R2I') THEN !
C=X(J) !
ELSE IF(TR == 'I2R') THEN !
C=ONE !
END IF !
!
! Computing the integrand functions
!
DO K=2,NS-1 !
IF(K /= J) THEN !
G1(K)=(F0(K)-F0(J)) / & !
(X(K)*X(K)-X(J)*X(J)) !
END IF !
END DO !
R1=(X(1)-X(2))/(X(3)-X(2)) !
R2=(X(NS)-X(NS-1))/(X(NS-2)-X(NS-1)) !
G1(1)=G1(2)+R1*(G1(3)-G1(2)) !
G1(NS)=G1(NS-1)+R2*(G1(NS-2)-G1(NS-1)) !
IF( (J /= 1) .AND. (J /= NS) ) THEN !
G1(J)=HALF*(G1(J-1)+G1(J+1)) !
END IF !
!
! Computing the integrals with Lagrange method
!
CALL INTEGR_L(G1,H,NS,NSIZE1,I1,ID) !
!
! Result of transform
!
U_OUT(J)=ADD - C * COEF * I1 !
END DO !
!
! Format
!
10 FORMAT(//,5X,'<<<<< Size > NSIZE >>>>>', & !
/,5X,'<<<<< Increase NSIZE >>>>>',//) !
!
END SUBROUTINE KK
!
!
END MODULE TRANSFORMS