*IF DEF,A01_1A,OR,DEF,A01_1B,OR,DEF,A01_2A,OR,DEF,A01_2B,OR,DEF,A01_3A     AWI3F402.7      
C ******************************COPYRIGHT******************************    GTS2F400.9307   
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved.    GTS2F400.9308   
C                                                                          GTS2F400.9309   
C Use, duplication or disclosure of this code is subject to the            GTS2F400.9310   
C restrictions as set forth in the contract.                               GTS2F400.9311   
C                                                                          GTS2F400.9312   
C                Meteorological Office                                     GTS2F400.9313   
C                London Road                                               GTS2F400.9314   
C                BRACKNELL                                                 GTS2F400.9315   
C                Berkshire UK                                              GTS2F400.9316   
C                RG12 2SZ                                                  GTS2F400.9317   
C                                                                          GTS2F400.9318   
C If no contract has been raised with this copy of the code, the use,      GTS2F400.9319   
C duplication or disclosure of it is strictly prohibited.  Permission      GTS2F400.9320   
C to do so must first be obtained in writing from the Head of Numerical    GTS2F400.9321   
C Modelling at the above address.                                          GTS2F400.9322   
C ******************************COPYRIGHT******************************    GTS2F400.9323   
C                                                                          GTS2F400.9324   
CLL  Subroutine SOLANG -----------------------------------------------     SOLANG1A.3      
CLL                                                                        SOLANG1A.4      
CLL Purpose :                                                              SOLANG1A.5      
CLL  Calculations of the earth's orbit described in the second page of     SOLANG1A.6      
CLL  the "Calculation of incoming insolation" section of UMDP 23, i.e.     SOLANG1A.7      
CLL  from the sin of the solar  declination, the position of each point    SOLANG1A.8      
CLL  and the time limits it calculates how much sunlight, if any, it       SOLANG1A.9      
CLL  receives.                                                             SOLANG1A.10     
CLL                                                                        SOLANG1A.11     
CLL    Author:    William Ingram                                           SOLANG1A.12     
CLL  Model            Modification history from model version 3.0:         SOLANG1A.13     
CLL version  Date                                                          SOLANG1A.14     
CLL                                                                        SOLANG1A.15     
CLL Programming standard :                                                 SOLANG1A.16     
CLL    Written to comply with 12/9/89 version of UMDP 4 (meteorological    SOLANG1A.17     
CLL  standard).                                                            SOLANG1A.18     
CLL    Written in FORTRAN 77 with the addition of "!" comments and         SOLANG1A.19     
CLL  underscores in variable names.                                        SOLANG1A.20     
CLL                                                                        SOLANG1A.21     
CLL Logical components covered : P233                                      SOLANG1A.22     
CLL                                                                        SOLANG1A.23     
CLL Project task :                                                         SOLANG1A.24     
CLL                                                                        SOLANG1A.25     
CLL External documentation: UMDP 23                                        SOLANG1A.26     
CLL                                                                        SOLANG1A.27     
CLLEND -----------------------------------------------------------------   SOLANG1A.28     
C*L                                                                        SOLANG1A.29     

      SUBROUTINE SOLANG (SINDEC, T, DT, SINLAT, LONGIT, K,                  5SOLANG1A.30     
     &     LIT, COSZ)                                                      SOLANG1A.31     
      INTEGER!, INTENT(IN) ::                                              SOLANG1A.32     
     &     K                          ! Number of points                   SOLANG1A.33     
      REAL!, INTENT(IN) ::                                                 SOLANG1A.34     
     &     SINDEC,                    ! Sin(solar declination)             SOLANG1A.35     
     &     T, DT,                     ! Start time (GMT) & timestep        SOLANG1A.36     
     &     SINLAT(K),                 ! sin(latitude) & longitude          SOLANG1A.37     
     &     LONGIT(K)                  ! of each point                      SOLANG1A.38     
      REAL!, INTENT(OUT) ::                                                SOLANG1A.39     
     &     LIT(K),                    ! Sunlit fraction of the timestep    SOLANG1A.40     
     &     COSZ(K)                    ! Mean cos(solar zenith angle)       SOLANG1A.41     
C                                     ! during the sunlit fraction         SOLANG1A.42     
C*                                                                         SOLANG1A.43     
CL This routine has no dynamically allocated work areas.  It calls the     SOLANG1A.44     
CL intrinsic functions SQRT, ACOS & SIN, but no user functions or          SOLANG1A.45     
CL subroutines.  The only structure is a loop over all the points to be    SOLANG1A.46     
CL dealt with, with IF blocks nested inside to cover the various           SOLANG1A.47     
CL possibilities.                                                          SOLANG1A.48     
      INTEGER J                       ! Loop counter over points           SOLANG1A.49     
      REAL TWOPI,                     ! 2*pi                               SOLANG1A.50     
     &     S2R                        ! Seconds-to-radians converter       SOLANG1A.51     
      REAL SINSIN,            ! Products of the sines and of the cosines   SOLANG1A.52     
     &     COSCOS,            ! of solar declination and of latitude.      SOLANG1A.53     
     &     HLD,               ! Half-length of the day in radians (equal   SOLANG1A.54     
     &                        ! to the hour-angle of sunset, and minus     SOLANG1A.55     
     &     COSHLD,            ! the hour-angle of sunrise) & its cosine.   SOLANG1A.56     
     &     HAT,               ! Local hour angle at the start time.        SOLANG1A.57     
     &     OMEGAB,            ! Beginning and end of the timestep and      SOLANG1A.58     
     &     OMEGAE,            ! of the period over which cosz is           SOLANG1A.59     
     &     OMEGA1,            ! integrated, and sunset - all measured in   SOLANG1A.60     
     &     OMEGA2,            ! radians after local sunrise, not from      SOLANG1A.61     
     &     OMEGAS,            ! local noon as the true hour angle is.      SOLANG1A.62     
     &     DIFSIN,            ! A difference-of-sines intermediate value   SOLANG1A.63     
     &     DIFTIM,            ! and the corresponding time period          SOLANG1A.64     
     &     TRAD, DTRAD                                                     SOLANG1A.65     
C     ! These are the start-time and length of the timestep (T & DT)       SOLANG1A.66     
C     ! converted to radians after midday GMT, or equivalently, hour       SOLANG1A.67     
C     ! angle of the sun on the Greenwich meridian.                        SOLANG1A.68     
*CALL C_PI                                                                 SOLANG1A.69     
      PARAMETER ( TWOPI = 2. * PI, S2R = PI / 43200.)                      SOLANG1A.70     
C                                                                          SOLANG1A.71     
      TRAD = T * S2R - PI                                                  SOLANG1A.72     
      DTRAD = DT * S2R                                                     SOLANG1A.73     
CDIR$ IVDEP                                                                SOLANG1A.74     
! Fujitsu vectorization directive                                          GRB0F405.549    
!OCL NOVREC                                                                GRB0F405.550    
      DO 100 J = 1, K                          ! Loop over points          SOLANG1A.75     
       HLD = 0.                                ! Logically unnecessary     SOLANG1A.76     
C statement without which the CRAY compiler will not vectorize this code   SOLANG1A.77     
       SINSIN = SINDEC * SINLAT(J)                                         SOLANG1A.78     
       COSCOS = SQRT( (1.-SINDEC**2) * (1.-SINLAT(J)**2) )                 SOLANG1A.79     
       COSHLD = SINSIN / COSCOS                                            SOLANG1A.80     
       IF (COSHLD.LT.-1.) THEN                 ! Perpetual night           SOLANG1A.81     
          LIT(J) = 0.                                                      SOLANG1A.82     
          COSZ(J) = 0.                                                     SOLANG1A.83     
        ELSE                                                               SOLANG1A.84     
          HAT = LONGIT(J) + TRAD               ! (3.2.2)                   SOLANG1A.85     
          IF (COSHLD.GT.1.) THEN               !   Perpetual day - hour    SOLANG1A.86     
             OMEGA1 = HAT                      ! angles for (3.2.3) are    SOLANG1A.87     
             OMEGA2 = HAT + DTRAD              ! start & end of timestep   SOLANG1A.88     
           ELSE                                !   At this latitude some   SOLANG1A.89     
C points are sunlit, some not.  Different ones need different treatment.   SOLANG1A.90     
             HLD = ACOS(-COSHLD)               ! (3.2.4)                   SOLANG1A.91     
C The logic seems simplest if one takes all "times" - actually hour        SOLANG1A.92     
C angles - relative to sunrise (or sunset), but they must be kept in the   SOLANG1A.93     
C range 0 to 2pi for the tests on their orders to work.                    SOLANG1A.94     
             OMEGAB = HAT + HLD                                            SOLANG1A.95     
             IF (OMEGAB.LT.0.)   OMEGAB = OMEGAB + TWOPI                   SOLANG1A.96     
             IF (OMEGAB.GE.TWOPI) OMEGAB = OMEGAB - TWOPI                  SOLANG1A.97     
             IF (OMEGAB.GE.TWOPI) OMEGAB = OMEGAB - TWOPI                  SOLANG1A.98     
C            !  Line repeated - otherwise could have failure if            SOLANG1A.99     
C            !  longitudes W are > pi rather than < 0.                     SOLANG1A.100    
             OMEGAE = OMEGAB + DTRAD                                       SOLANG1A.101    
             IF (OMEGAE.GT.TWOPI) OMEGAE = OMEGAE - TWOPI                  SOLANG1A.102    
             OMEGAS = 2. * HLD                                             SOLANG1A.103    
C Now that the start-time, end-time and sunset are set in terms of hour    SOLANG1A.104    
C angle, can set the two hour-angles for (3.2.3).  The simple cases are    SOLANG1A.105    
C start-to-end-of-timestep, start-to-sunset, sunrise-to-end and sunrise-   SOLANG1A.106    
C -to-sunset, but two other cases exist and need special treatment.        SOLANG1A.107    
             IF (OMEGAB.LE.OMEGAS .OR. OMEGAB.LT.OMEGAE) THEN              SOLANG1A.108    
                OMEGA1 = OMEGAB - HLD                                      SOLANG1A.109    
              ELSE                                                         SOLANG1A.110    
                OMEGA1 = - HLD                                             SOLANG1A.111    
             ENDIF                                                         SOLANG1A.112    
             IF (OMEGAE.LE.OMEGAS) THEN                                    SOLANG1A.113    
                OMEGA2 = OMEGAE - HLD                                      SOLANG1A.114    
              ELSE                                                         SOLANG1A.115    
                OMEGA2 = OMEGAS - HLD                                      SOLANG1A.116    
             ENDIF                                                         SOLANG1A.117    
             IF (OMEGAE.GT.OMEGAB.AND.OMEGAB.GT.OMEGAS) OMEGA2=OMEGA1      SOLANG1A.118    
C  Put in an arbitrary marker for the case when the sun does not rise      SOLANG1A.119    
C  during the timestep (though it is up elsewhere at this latitude).       SOLANG1A.120    
C  (Cannot set COSZ & LIT within the ELSE ( COSHLD < 1 ) block             SOLANG1A.121    
C  because 3.2.3 is done outside this block.)                              SOLANG1A.122    
          ENDIF           ! This finishes the ELSE (perpetual day) block   SOLANG1A.123    
          DIFSIN = SIN(OMEGA2) - SIN(OMEGA1)             ! Begin (3.2.3)   SOLANG1A.124    
          DIFTIM = OMEGA2 - OMEGA1                                         SOLANG1A.125    
C Next, deal with the case where the sun sets and then rises again         SOLANG1A.126    
C within the timestep.  There the integration has actually been done       SOLANG1A.127    
C backwards over the night, and the resulting negative DIFSIN and DIFTIM   SOLANG1A.128    
C must be combined with positive values representing the whole of the      SOLANG1A.129    
C timestep to get the right answer, which combines contributions from      SOLANG1A.130    
C the two separate daylit periods.  A simple analytic expression for the   SOLANG1A.131    
C total sun throughout the day is used.  (This could of course be used     SOLANG1A.132    
C alone at points where the sun rises and then sets within the timestep)   SOLANG1A.133    
          IF (DIFTIM.LT.0.) THEN                                           SOLANG1A.134    
            DIFSIN = DIFSIN + 2. * SQRT(1.-COSHLD**2)                      SOLANG1A.135    
            DIFTIM = DIFTIM + 2. * HLD                                     SOLANG1A.136    
          ENDIF                                                            SOLANG1A.137    
          IF (DIFTIM.EQ.0.) THEN                                           SOLANG1A.138    
C Pick up the arbitrary marker for night points at a partly-lit latitude   SOLANG1A.139    
             COSZ(J) = 0.                                                  SOLANG1A.140    
             LIT(J) = 0.                                                   SOLANG1A.141    
           ELSE                                                            SOLANG1A.142    
             COSZ(J) = DIFSIN*COSCOS/DIFTIM + SINSIN     ! (3.2.3)         SOLANG1A.143    
             LIT(J) = DIFTIM / DTRAD                                       SOLANG1A.144    
          ENDIF                                                            SOLANG1A.145    
       ENDIF            ! This finishes the ELSE (perpetual night) block   SOLANG1A.146    
  100 CONTINUE                                                             SOLANG1A.147    
      RETURN                                                               SOLANG1A.148    
      END                                                                  SOLANG1A.149    
*ENDIF DEF,A01_1A,OR,DEF,A01_1B,OR,DEF,A01_2A,OR,DEF,A01_3A                ADB1F400.383