Can anyone tell me about the costh
variable used in the following subroutine? From where is the subroutine obtaining the value of this variable? Is it some error or inbuilt function?
The complete subroutine is given below.
SUBROUTINE MOMENT(I,A,AP,MODE,EP,NCASC,ID)
COMMON/MOM/VY(99996),VZ(99996),VX(99996)
DIMENSION ERES(99996),FCT(99996)
COMMON/XQANG/SUM(300,10),MDIR,COSTH
EQUIVALENCE(ERES(1),VY(1)),(FCT(1),VZ(1))
IF(ID-2)10,30,40
C INITIALIZATION
10 N=1
NN=N+NCASC-1
DO 20 J=N,NN
VY(J)=EP*MDIR
VX(J)=0.
20 VZ(J)=EP*(1-MDIR)
GO TO 60
C
C CALCULATION OF MOMENT
C
CKM 30 RN4=RANF(0.)
30 RN4=RAN(ISEED) !KM
PHI=6.28318*RN4
SOX=2.*AP*EP/(A**2*931.5)
C BUG FIX A*(AP+A)REPLACED BY A**2 12/15/82
C IF(SOX.LT.0.)WRITE(*,943)AP,EP,A
VT=SQRT(SOX)
SOX=1.-COSTH**2
IF(SOX.LT.0.)SOX=0.
SINTH=SQRT(SOX)
VZSE=VT*COSTH
VYSE=VT*SINTH*SIN(PHI)
VXSE=VT*SINTH*COS(PHI)
VZ(I)=VZ(I)+VZSE
VY(I)=VY(I)+VYSE
VX(I)=VX(I)+VXSE
VZP=VZ(I)-VZSE*(A/AP+1.)
VYP=VY(I)-VYSE*(A/AP+1.)
VXP=VX(I)-VXSE*(A/AP+1.)
VPP2=VZP*VZP+VYP*VYP+VXP*VXP
EPART=AP*VPP2*469.
SOX=0.
IF(VPP2.GT.0.0)SOX=VZP/SQRT(VPP2)
C DO NOT USE QUICK FUNCTIONS HERE
ANG=ACOS(SOX)*180./3.1415927
CALL OUTEM(2,MODE,EPART,ANG)
GO TO 60
C
C END CALCULATION
C
40 VFTS=VX(I)**2+VY(I)**2+VZ(I)**2
ERES(I)=0.5*A*VFTS*931.5
IF(VFTS.NE.0.)GO TO 50
FCT(I)=0.0
GO TO 60
50 FCT(I)=ACOS(VZ(I)/SQRT(VFTS))*180./3.1415927
60 RETURN
END
This line
COMMON/XQANG/SUM(300,10),MDIR,COSTH
informs the subroutine about a common block called XQANG
which has an element called COSTH
. In the absence of other information, and in a code of that vintage, this is most likely to be a real
variable.
Common blocks are an early-Fortran mechanism for sharing variables across program units, such as between a main program and a subroutine. In straightforward use the same common block declaration will be found in multiple locations, with the same list of variables. Each declaration refers to the same variables.
There is a twist though, and one to watch out for carefully. The common block is actually a shared block of memory, and there is no requirement that each instance of the declaration identify the same variables. One common use of common blocks was to declare, say, an array of 100 reals in one location, but to declare two arrays each of 50 reals elsewhere -- same memory, different variables.
Even better, they could also be used to change the types of variables (sort of). One usage of a common block might contain a real variable occupying 4 bytes, while another usage of the same block might contain a 4-byte integer variable at the same location - same bits, different interpretations.
These twists are among the reasons for common blocks being widely deprecated. Another reason for their deprecation is that they obscure the sharing of variables, these days most of us prefer to explicitly pass arguments into and out of subroutines through their argument lists.
I'd guess very few Fortran programmers under 50 are still writing new code using them. But Fortran programmers from 8 - 80 are still working on codes containing them.