SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
oi_tsl.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 SUBROUTINE oi_tsl(KDAT,KSSSSS,PLAT,PLON,PMU0,PMU0M,KH)
6 !-----------------------------------------------------------------------
7 !
8 ! Computation of solar zenith angle
9 ! ---------------------------------
10 !
11 ! INPUT PARAMETERS :
12 !
13 ! IDAT : DATE in the following form => YYYYMMDD
14 ! NSSSSS : TIME of the day in seconds
15 ! PLAT : LATITUDE in Degrees
16 ! PLON : LONGITUDE in Degrees
17 !
18 ! OUTPUT PARAMETERS :
19 !
20 ! PMU0 : Cosine of solar zenith angle
21 ! PMU0M : Cosine of solar zenith angle (mean value)
22 ! IH : local time (hour)
23 !
24 !
25 ! J.F. Mahfouf (4/12/97) from IFS/ARPEGE routines
26 !
27 !
28 ! 23/05/2009 : Fortran 90 recoding (IMPLICIT NONE + FUNCTIONS)
29 !
30 !-----------------------------------------------------------------------
31 !
32 ! - Astronomical functions
33 ! you will find the description in the annex 1 of the documentation
34 ! RRS is the distance Sun-Earth
35 ! RDS is the declination of the Earth
36 ! RET is the equation of time
37 !
38 USE modd_csts, ONLY : xpi
39 USE modd_assim, ONLY : xrepsm, xrcdtr, nitrad
40 !
41 !
42 USE yomhook, ONLY : lhook, dr_hook
43 USE parkind1, ONLY : jprb
44 !
45 IMPLICIT NONE
46 !
47 INTEGER, INTENT(IN) :: kdat
48 INTEGER, INTENT(IN) :: ksssss
49 REAL, INTENT(IN) :: plat, plon
50 REAL, INTENT(OUT) :: pmu0, pmu0m
51 INTEGER, INTENT(OUT) :: kh
52 !
53 REAL :: zgemu, zgelam, ztime, zteta, zrdecli, zreqtim, zrhgmt, zrsovr, &
54  zrwsovr, zrcodec, zrsidec, zrcovsr, zrsivsr, zrtimtrm, ztetam, &
55  zrdeclim, zreqtimm, zrhgmtm, zrsovrm, zrwsovrm, zrcodecm, &
56  zrsidecm, zrcovsrm, zrsivsrm, zt
57 INTEGER :: id, im, ia, insssss
58 REAL(KIND=JPRB) :: zhook_handle
59 !
60 ! Angle conversions
61 !
62 IF (lhook) CALL dr_hook('OI_TSL',0,zhook_handle)
63 !
64 zgemu = sin(plat*xpi/180.) ! sinus of latitude
65 zgelam = plon*xpi/180. ! longitude
66 !
67 id = mod(kdat,100)
68 im = mod((kdat-id)/100,100)
69 ia = kdat/10000
70 
71 ztime = rtime(ia,im,id,ksssss)
72 !
73  CALL get_mu0(zgemu,zgelam,ztime,ksssss,pmu0)
74 !
75 !
76 ! Mean angle over the previous 6 hours
77 ! ------------------------------------
78 !
79 ztime = rtime(ia,im,id,ksssss-nitrad)
80 !
81 IF ( (ksssss-nitrad).LT.0 ) THEN
82  insssss = ksssss + 86400
83 ELSE
84  insssss = ksssss
85 ENDIF
86 !
87  CALL get_mu0(zgemu,zgelam,ztime,insssss-nitrad,pmu0m)
88 !
89 !
90 ! Local time in hours
91 ! Should be inside [1,24]
92 !
93 zt = (ksssss + plon*xrcdtr*3600.)/3600.
94 IF (zt < 0.0) THEN
95  zt = zt + 24.
96 ELSEIF (zt > 24.0) THEN
97  zt = zt - 24.
98 ENDIF
99 !
100 kh = int(zt)
101 IF ( kh==0 ) kh = 24
102 !
103 IF (lhook) CALL dr_hook('OI_TSL',1,zhook_handle)
104 !
105  CONTAINS
106 !
107 SUBROUTINE get_mu0(PGEMU,PGELAM,PTIME,KSSSSS,PMU)
108 !
109 USE modd_csts, ONLY : xday
110 !
111 IMPLICIT NONE
112 !
113 REAL, INTENT(IN) :: pgemu
114 REAL, INTENT(IN) :: pgelam
115 REAL, INTENT(IN) :: ptime
116 INTEGER, INTENT(IN) :: ksssss
117 REAL, INTENT(OUT) :: pmu
118 !
119 REAL :: zteta, zdecli, zeqtim, zhgmt, zwsovr
120 REAL :: zinter
121 !
122 zteta = ptime/(xday*365.25)
123 !
124 zdecli = rds(zteta) ! declinaison
125 !
126 zeqtim = ret(zteta)
127 zhgmt = REAL( MOD(KSSSSS,NINT(XDAY)) )
128 zwsovr = (zeqtim + zhgmt) * 2. * xpi/xday ! hour angle
129 !
130 zinter = sqrt(1.-pgemu**2)
131 pmu = max( sin(zdecli) * pgemu + cos(zdecli) * zinter * &
132  ( sin(zwsovr)*sin(pgelam) - cos(zwsovr)*cos(pgelam) ) , 0. )
133 !
134 IF (pmu.GT.0.) pmu = sqrt(1224.*pmu*pmu +1.)/35. ! Magnification factor
135 !
136 END SUBROUTINE get_mu0
137 !
138 FUNCTION rds(PT)
139 
140 USE modd_assim, ONLY : xrepsm
141 
142 IMPLICIT NONE
143 
144 REAL, INTENT(IN) :: pt
145 REAL :: rds, zls, zel
146 REAL(KIND=JPRB) :: zhook_handle
147 
148 IF (lhook) CALL dr_hook('RDS',0,zhook_handle)
149 !
150 zel = 1.7535 + 6.283076 * pt
151 zls = 4.8952 + 6.283320 * pt &
152  - 0.0075*sin(zel) - 0.0326*cos(zel) &
153  - 0.0003*sin(2.*zel) + 0.0002*cos(2.*zel)
154 !
155 rds = asin(sin(xrepsm)*sin(zls))
156 !
157 IF (lhook) CALL dr_hook('RDS',1,zhook_handle)
158 
159 END FUNCTION rds
160 !
161 FUNCTION ret(PT)
162 
163 IMPLICIT NONE
164 
165 REAL, INTENT(IN) :: pt
166 REAL :: ret, zem, zls
167 REAL(KIND=JPRB) :: zhook_handle
168 
169 IF (lhook) CALL dr_hook('RET',0,zhook_handle)
170 
171 zem = 6.240075 + 6.283020 * pt
172 zls = 4.8951 + 6.283076 * pt
173 ret = 591.8*sin(2.*zls) - 12.7 * sin(4.*zls) &
174  - 459.4*sin(zem) - 4.8 *sin(2.*zem) &
175  + 39.5 * sin(zem) * cos(2.*zls)
176 
177 IF (lhook) CALL dr_hook('RET',1,zhook_handle)
178 
179 END FUNCTION ret
180 !
181 FUNCTION rtime(KA,KM,KD,KS)
182 
183 USE modd_csts, ONLY : xday
184 
185 IMPLICIT NONE
186 
187 INTEGER, INTENT(IN) :: ka, km, kd, ks
188 REAL :: rtime, zj
189 INTEGER :: ia, im
190 REAL(KIND=JPRB) :: zhook_handle
191 
192 IF (lhook) CALL dr_hook('RTIME',0,zhook_handle)
193 
194 im = km + 6*(1-isign(1,km-3))
195 ia = ka - ( (1-isign(1,km-3))/2 )
196 !
197 zj = 1720994.5 + &
198  float( 2 - ia/100 + (ia/100)/4 + &
199  int(365.25*float(ia)) + int(30.601*float(im+1)) + kd )
200 !
201 rtime = (zj-2451545.)*xday + float(ks)
202 !
203 IF (lhook) CALL dr_hook('RTIME',1,zhook_handle)
204 
205 END FUNCTION rtime
206 
207 END SUBROUTINE oi_tsl
208 
209 
210 
211 
subroutine get_mu0(PGEMU, PGELAM, PTIME, KSSSSS, PMU)
Definition: oi_tsl.F90:107
real function rds(PT)
Definition: oi_tsl.F90:138
subroutine oi_tsl(KDAT, KSSSSS, PLAT, PLON, PMU0, PMU0M, KH)
Definition: oi_tsl.F90:5
real function ret(PT)
Definition: oi_tsl.F90:161
real function rtime(KA, KM, KD, KS)
Definition: oi_tsl.F90:181