Search code examples
fortranfortran-common-block

Where does this Fortran variable come from?


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

Solution

  • 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.