MODULE GlobalMath IMPLICIT NONE REAL(8) :: pi , machine_precision , machine_zero , machine_infinity REAL(8), PRIVATE :: minlog,maxlog,minexp,maxexp REAL(8), PRIVATE :: minlogarg,maxlogarg,minexparg,maxexparg CONTAINS !**************************************************** SUBROUTINE Init_GlobalConstants INTEGER :: i REAL(8) :: tmp , a1,a2,a3 ! Calculate machine accuracy machine_precision = 0 a1 = 4.d0/3.d0 DO WHILE (machine_precision == 0.d0) a2 = a1 - 1.d0 a3 = a2 + a2 + a2 machine_precision = ABS(a3 - 1.d0) ENDDO machine_zero= machine_precision**4 machine_infinity = 1.d0/machine_zero pi = ACOS(-1.d0) minlogarg=machine_precision; minlog=LOG(minlogarg) maxlogarg=1.d0/machine_precision; maxlog=LOG(maxlogarg) minexparg=LOG(machine_precision); minexp=0.d0 maxexparg=-LOG(machine_precision); maxexp=EXP(maxexparg) RETURN END SUBROUTINE Init_GlobalConstants !**************************************************** FUNCTION ddlog(arg) REAL(8) :: arg,ddlog IF (arg>maxlogarg) THEN ddlog=maxlog ELSE IF (argmaxexparg) THEN ddexp=maxexp ELSE IF (arg=4) THEN DO i=4,j,2 overint=overint+f1(i-2)+4*f1(i-1)+f1(i) ENDDO overint=fac*overint ENDIF IF (n>j) THEN overint=overint+(f1(j)+f1(n))*h/2 ENDIF RETURN END FUNCTION overint !***************************************************************** FUNCTION overlap(n,h,f1,f2) ! function to calculate the overlap between two vectors f1 and f2 ! using simpsons rule, assuming f1(0)*f2(0)=0 ! assumes f1, f2 tabulated at points r=i*h REAL(8) :: overlap INTEGER, INTENT(IN) :: n REAL(8), INTENT(IN) :: h, f1(n),f2(n) INTEGER :: i,j REAL(8) :: fac IF (n==1) THEN overlap=h*f1(1)*f2(1)/2 RETURN ENDIF fac=h/3 overlap=4*f1(1)*f2(1)+f1(2)*f2(2) j=(n/2)*2 IF(j>=4) THEN DO i=4,j,2 overlap=overlap+f1(i-2)*f2(i-2)+4*f1(i-1)*f2(i-1)+f1(i)*f2(i) ENDDO overlap=fac*overlap ENDIF IF (n>j) THEN overlap=overlap+h*(f1(j)*f2(j)+f1(n)*f2(n))/2 ENDIF RETURN END FUNCTION overlap SUBROUTINE thomas(n,a,b,c,d) ! subroutine to use Thomas's algorithm to solve tridiagonal matrix ! Dale U. von Rosenberg, "Methods for the Numerical Solution of ! Partial Differential Equations, Am. Elsevier Pub., 1969, pg. 113 ! a(i)*u(i-1)+b(i)*u(i)+c(i)*u(i+1)=d(i) ! a(1)=c(n)==0 ! upon return, d(i)=u(i), a,b, & c modified INTEGER, INTENT(IN) :: n REAL(8), INTENT(INOUT) :: a(n),b(n),c(n),d(n) INTEGER :: i IF (n.LT.1) THEN WRITE(6,*) '***error in thomas -- n = ',n STOP ELSE IF (n.EQ.1) THEN d(1)=d(1)/b(1) RETURN ELSE DO i=2,n b(i)=b(i)-a(i)*c(i-1)/b(i-1) ENDDO d(1)=d(1)/b(1) DO i=2,n d(i)=(d(i)-a(i)*d(i-1))/b(i) ENDDO DO i=n-1,1,-1 d(i)=d(i)-c(i)*d(i+1)/b(i) ENDDO ENDIF RETURN END SUBROUTINE thomas !********************************************************************** FUNCTION ranx() REAL(8) :: ranx INTEGER, PARAMETER :: konst=125 INTEGER :: m=100001 m=m*konst m=m-2796203*(m/2796203) ranx=m/2796203.d0 RETURN END FUNCTION ranx SUBROUTINE shift4(v1,v2,v3,v4,NEW) REAL(8), INTENT(IN) :: NEW REAL(8), INTENT(INOUT) :: v1,v2,v3,v4 v1=v2 v2=v3 v3=v4 v4=NEW RETURN END SUBROUTINE shift4 SUBROUTINE mkname(i,stuff) ! subroutine to take an integer (.le. 4 digits) and return it ! in the form of a character string CHARACTER(4) stuff INTEGER i,i1,i10,i100,i1000 stuff='?' IF (i.GT.10000) i=MOD(i,10000) i1000=i/1000 i100=(i-1000*i1000)/100 i10=(i-1000*i1000-100*i100)/10 i1=(i-1000*i1000-100*i100-10*i10) IF (i.GE.1000) THEN stuff=CHAR(i1000+48)//CHAR(i100+48)//CHAR(i10+48)//CHAR(i1+48) RETURN ENDIF IF (i.GE.100) THEN stuff=CHAR(i100+48)//CHAR(i10+48)//CHAR(i1+48) RETURN ENDIF IF (i.GE.10) THEN stuff=CHAR(i10+48)//CHAR(i1+48) RETURN ENDIF IF (i.GE.0) stuff=CHAR(i1+48) RETURN END SUBROUTINE mkname END MODULE GlobalMath