1 |
molod |
1.1 |
C $Header: $ |
2 |
|
|
C $Name: $ |
3 |
|
|
|
4 |
|
|
#include "PACKAGES_CONFIG.h" |
5 |
|
|
#include "CPP_OPTIONS.h" |
6 |
|
|
subroutine set_alarm (tag,date,time,freq) |
7 |
|
|
C*********************************************************************** |
8 |
|
|
C Purpose |
9 |
|
|
C ------- |
10 |
|
|
C Utility to Set Internal Alarms |
11 |
|
|
C |
12 |
|
|
C Argument Description |
13 |
|
|
C -------------------- |
14 |
|
|
C tag ....... Character String Tagging Alarm Process |
15 |
|
|
C date ...... Begining Date for Alarm |
16 |
|
|
C time ...... Begining Time for Alarm |
17 |
|
|
C freq ...... Repeating Frequency Interval for Alarm |
18 |
|
|
C |
19 |
|
|
C*********************************************************************** |
20 |
|
|
|
21 |
|
|
implicit none |
22 |
|
|
character*(*) tag |
23 |
|
|
integer freq,date,time |
24 |
|
|
|
25 |
|
|
#ifdef ALLOW_USE_MPI |
26 |
|
|
#include "SIZE.h" |
27 |
|
|
#include "EEPARAMS.h" |
28 |
|
|
#include "EESUPPORT.h" |
29 |
|
|
#endif |
30 |
|
|
|
31 |
|
|
#include "chronos.h" |
32 |
|
|
|
33 |
|
|
#ifdef ALLOW_USE_MPI |
34 |
|
|
c MPI Utilities |
35 |
|
|
c ------------- |
36 |
|
|
#include "mpif.h" |
37 |
|
|
integer mpi_comm_model,ierror |
38 |
|
|
#endif |
39 |
|
|
|
40 |
|
|
integer myid |
41 |
|
|
logical first,set |
42 |
|
|
data first /.true./ |
43 |
|
|
|
44 |
|
|
integer n |
45 |
|
|
#ifdef ALLOW_USE_MPI |
46 |
|
|
call mpi_comm_rank ( mpi_comm_model,myid,ierror ) |
47 |
|
|
#else |
48 |
|
|
myid = 1 |
49 |
|
|
#endif |
50 |
|
|
|
51 |
|
|
if(first) then |
52 |
|
|
ntags = 1 |
53 |
|
|
tags(1) = tag |
54 |
|
|
freqs(1) = freq |
55 |
|
|
dates(1) = date |
56 |
|
|
times(1) = time |
57 |
|
|
if( myid.eq.1 ) write(6,100) date,time,freq,tags(1) |
58 |
|
|
else |
59 |
|
|
|
60 |
|
|
set = .false. |
61 |
|
|
do n=1,ntags |
62 |
|
|
if(tag.eq.tags(n)) then |
63 |
|
|
if( myid.eq.1 ) then |
64 |
|
|
print *, 'Warning! Alarm has already been set for Tag: ',tag |
65 |
|
|
print *, 'Changing Alarm Information:' |
66 |
|
|
print *, 'Frequency: ',freqs(n),' (Old) ',freq,' (New)' |
67 |
|
|
print *, ' Date0: ',dates(n),' (Old) ',date,' (New)' |
68 |
|
|
print *, ' Time0: ',times(n),' (Old) ',time,' (New)' |
69 |
|
|
endif |
70 |
|
|
freqs(n) = freq |
71 |
|
|
dates(n) = date |
72 |
|
|
times(n) = time |
73 |
|
|
set = .true. |
74 |
|
|
endif |
75 |
|
|
enddo |
76 |
|
|
if(.not.set) then |
77 |
|
|
ntags = ntags+1 |
78 |
|
|
if(ntags.gt.maxtag ) then |
79 |
|
|
if( myid.eq.1 ) then |
80 |
|
|
print *, 'Too many Alarms are Set!!' |
81 |
|
|
print *, 'Maximum Number of Alarms = ',maxtag |
82 |
|
|
endif |
83 |
|
|
call my_finalize |
84 |
|
|
call my_exit (101) |
85 |
|
|
endif |
86 |
|
|
tags(ntags) = tag |
87 |
|
|
freqs(ntags) = freq |
88 |
|
|
dates(ntags) = date |
89 |
|
|
times(ntags) = time |
90 |
|
|
if( myid.eq.1 ) write(6,100) date,time,freq,tags(ntags) |
91 |
|
|
endif |
92 |
|
|
endif |
93 |
|
|
|
94 |
|
|
first = .false. |
95 |
|
|
100 format(1x,'Setting Alarm for: ',i8,2x,i6.6,', with frequency: ', |
96 |
|
|
. i8,', and Tag: ',a80) |
97 |
|
|
return |
98 |
|
|
end |
99 |
|
|
|
100 |
|
|
subroutine get_alarm (tag,date,time,freq,tleft) |
101 |
|
|
C*********************************************************************** |
102 |
|
|
C Purpose |
103 |
|
|
C ------- |
104 |
|
|
C Utility to Get Internal Alarm Information |
105 |
|
|
C |
106 |
|
|
C Input |
107 |
|
|
C ----- |
108 |
|
|
C tag ....... Character String Tagging Alarm Process |
109 |
|
|
C |
110 |
|
|
C Output |
111 |
|
|
C ------ |
112 |
|
|
C date ...... Begining Date for Alarm |
113 |
|
|
C time ...... Begining Time for Alarm |
114 |
|
|
C freq ...... Frequency Interval for Alarm |
115 |
|
|
C tleft ..... Time Remaining (seconds) before Alarm is TRUE |
116 |
|
|
C |
117 |
|
|
C*********************************************************************** |
118 |
|
|
|
119 |
|
|
implicit none |
120 |
|
|
character*(*) tag |
121 |
|
|
integer freq,date,time,tleft |
122 |
|
|
|
123 |
|
|
#ifdef ALLOW_USE_MPI |
124 |
|
|
#include "SIZE.h" |
125 |
|
|
#include "EEPARAMS.h" |
126 |
|
|
#include "EESUPPORT.h" |
127 |
|
|
#endif |
128 |
|
|
|
129 |
|
|
#include "chronos.h" |
130 |
|
|
|
131 |
|
|
#ifdef ALLOW_USE_MPI |
132 |
|
|
c MPI Utilities |
133 |
|
|
c ------------- |
134 |
|
|
#include "mpif.h" |
135 |
|
|
integer mpi_comm_model,ierror |
136 |
|
|
#endif |
137 |
|
|
|
138 |
|
|
logical set,alarm |
139 |
|
|
external alarm |
140 |
|
|
integer myid,n,nalarm,nsecf |
141 |
|
|
|
142 |
|
|
#ifdef ALLOW_USE_MPI |
143 |
|
|
call mpi_comm_rank ( mpi_comm_model,myid,ierror ) |
144 |
|
|
#else |
145 |
|
|
myid = 1 |
146 |
|
|
#endif |
147 |
|
|
|
148 |
|
|
set = .false. |
149 |
|
|
do n=1,ntags |
150 |
|
|
if(tag.eq.tags(n)) then |
151 |
|
|
freq = freqs(n) |
152 |
|
|
date = dates(n) |
153 |
|
|
time = times(n) |
154 |
|
|
|
155 |
|
|
if( alarm(tag) ) then |
156 |
|
|
tleft = 0 |
157 |
|
|
else |
158 |
|
|
call get_time (nymd,nhms) |
159 |
|
|
tleft = nsecf(freq) - nalarm(freq,nymd,nhms,date,time ) |
160 |
|
|
endif |
161 |
|
|
|
162 |
|
|
set = .true. |
163 |
|
|
endif |
164 |
|
|
enddo |
165 |
|
|
|
166 |
|
|
if(.not.set) then |
167 |
|
|
if( myid.eq.1 ) print *, 'Alarm has not been set for Tag: ',tag |
168 |
|
|
freq = 0 |
169 |
|
|
date = 0 |
170 |
|
|
time = 0 |
171 |
|
|
tleft = 0 |
172 |
|
|
endif |
173 |
|
|
|
174 |
|
|
return |
175 |
|
|
end |
176 |
|
|
|
177 |
|
|
function alarm (tag) |
178 |
|
|
implicit none |
179 |
|
|
character*(*) tag |
180 |
|
|
integer date,time |
181 |
|
|
logical alarm |
182 |
|
|
#include "chronos.h" |
183 |
|
|
|
184 |
|
|
integer n,modalarm,nalarm,freq,date0,time0 |
185 |
|
|
modalarm(freq,date0,time0) = nalarm (freq,date,time,date0,time0 ) |
186 |
|
|
|
187 |
|
|
call get_time (date,time) |
188 |
|
|
|
189 |
|
|
alarm = .false. |
190 |
|
|
do n=1,ntags |
191 |
|
|
if( tags(n).eq.tag ) then |
192 |
|
|
if( freqs(n).eq.0 ) then |
193 |
|
|
alarm = (dates(n).eq.date) .and. (times(n).eq.time) |
194 |
|
|
else |
195 |
|
|
alarm = ( date.gt.dates(n) .or. |
196 |
|
|
. (date.eq.dates(n) .and. time.ge.times(n)) ) .and. |
197 |
|
|
. modalarm( freqs(n),dates(n),times(n) ).eq.0 |
198 |
|
|
endif |
199 |
|
|
endif |
200 |
|
|
enddo |
201 |
|
|
|
202 |
|
|
return |
203 |
|
|
end |
204 |
|
|
|
205 |
|
|
subroutine set_time (date,time) |
206 |
|
|
implicit none |
207 |
|
|
integer date,time |
208 |
|
|
|
209 |
|
|
#ifdef ALLOW_USE_MPI |
210 |
|
|
#include "SIZE.h" |
211 |
|
|
#include "EEPARAMS.h" |
212 |
|
|
#include "EESUPPORT.h" |
213 |
|
|
#endif |
214 |
|
|
|
215 |
|
|
#include "chronos.h" |
216 |
|
|
|
217 |
|
|
#ifdef ALLOW_USE_MPI |
218 |
|
|
c MPI Utilities |
219 |
|
|
c ------------- |
220 |
|
|
#include "mpif.h" |
221 |
|
|
integer mpi_comm_model,ierror |
222 |
|
|
#endif |
223 |
|
|
integer myid |
224 |
|
|
|
225 |
|
|
#ifdef ALLOW_USE_MPI |
226 |
|
|
call mpi_comm_rank ( mpi_comm_model,myid,ierror ) |
227 |
|
|
#else |
228 |
|
|
myid = 1 |
229 |
|
|
#endif |
230 |
|
|
if( myid.eq.1 ) then |
231 |
|
|
print *, 'Setting Clock' |
232 |
|
|
print *, 'Date: ',date |
233 |
|
|
print *, 'Time: ',time |
234 |
|
|
endif |
235 |
|
|
|
236 |
|
|
nymd = date |
237 |
|
|
nhms = time |
238 |
|
|
return |
239 |
|
|
end |
240 |
|
|
|
241 |
|
|
subroutine get_time (date,time) |
242 |
|
|
implicit none |
243 |
|
|
integer date,time |
244 |
|
|
|
245 |
|
|
#include "chronos.h" |
246 |
|
|
|
247 |
|
|
date = nymd |
248 |
|
|
time = nhms |
249 |
|
|
return |
250 |
|
|
end |
251 |
|
|
|
252 |
|
|
function nsecf (nhms) |
253 |
|
|
C*********************************************************************** |
254 |
|
|
C Purpose |
255 |
|
|
C Converts NHMS format to Total Seconds |
256 |
|
|
C |
257 |
|
|
C*********************************************************************** |
258 |
|
|
implicit none |
259 |
|
|
integer nhms, nsecf |
260 |
|
|
nsecf = nhms/10000*3600 + mod(nhms,10000)/100*60 + mod(nhms,100) |
261 |
|
|
return |
262 |
|
|
end |
263 |
|
|
|
264 |
|
|
function nhmsf (nsec) |
265 |
|
|
C*********************************************************************** |
266 |
|
|
C Purpose |
267 |
|
|
C Converts Total Seconds to NHMS format |
268 |
|
|
C |
269 |
|
|
C*********************************************************************** |
270 |
|
|
implicit none |
271 |
|
|
integer nhmsf, nsec |
272 |
|
|
nhmsf = nsec/3600*10000 + mod(nsec,3600)/60*100 + mod(nsec,60) |
273 |
|
|
return |
274 |
|
|
end |
275 |
|
|
|
276 |
|
|
function nsecf2 (nhhmmss,nmmdd,nymd) |
277 |
|
|
C*********************************************************************** |
278 |
|
|
C Purpose |
279 |
|
|
C Computes the Total Number of seconds from NYMD using NHHMMSS & NMMDD |
280 |
|
|
C |
281 |
|
|
C Arguments Description |
282 |
|
|
C NHHMMSS IntervaL Frequency (HHMMSS) |
283 |
|
|
C NMMDD Interval Frequency (MMDD) |
284 |
|
|
C NYMD Current Date (YYMMDD) |
285 |
|
|
C |
286 |
|
|
C NOTE: |
287 |
|
|
C IF (NMMDD.ne.0), THEN HOUR FREQUENCY HH MUST BE < 24 |
288 |
|
|
C |
289 |
|
|
C*********************************************************************** |
290 |
|
|
implicit none |
291 |
|
|
|
292 |
|
|
integer nsecf2,nhhmmss,nmmdd,nymd |
293 |
|
|
|
294 |
|
|
INTEGER NSDAY, NCYCLE |
295 |
|
|
PARAMETER ( NSDAY = 86400 ) |
296 |
|
|
PARAMETER ( NCYCLE = 1461*24*3600 ) |
297 |
|
|
|
298 |
|
|
INTEGER YEAR, MONTH, DAY |
299 |
|
|
|
300 |
|
|
INTEGER MNDY(12,4) |
301 |
|
|
DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366, |
302 |
|
|
. 397,34*0 / |
303 |
|
|
|
304 |
|
|
integer nsecf,i,nsegm,nsegd,iday,iday2,nday |
305 |
|
|
|
306 |
|
|
C*********************************************************************** |
307 |
|
|
C* COMPUTE # OF SECONDS FROM NHHMMSS * |
308 |
|
|
C*********************************************************************** |
309 |
|
|
|
310 |
|
|
nsecf2 = nsecf( nhhmmss ) |
311 |
|
|
|
312 |
|
|
if( nmmdd.eq.0 ) return |
313 |
|
|
|
314 |
|
|
C*********************************************************************** |
315 |
|
|
C* COMPUTE # OF DAYS IN A 4-YEAR CYCLE * |
316 |
|
|
C*********************************************************************** |
317 |
|
|
|
318 |
|
|
DO I=15,48 |
319 |
|
|
MNDY(I,1) = MNDY(I-12,1) + 365 |
320 |
|
|
ENDDO |
321 |
|
|
|
322 |
|
|
C*********************************************************************** |
323 |
|
|
C* COMPUTE # OF SECONDS FROM NMMDD * |
324 |
|
|
C*********************************************************************** |
325 |
|
|
|
326 |
|
|
nsegm = nmmdd/100 |
327 |
|
|
nsegd = mod(nmmdd,100) |
328 |
|
|
|
329 |
|
|
YEAR = NYMD / 10000 |
330 |
|
|
MONTH = MOD(NYMD,10000) / 100 |
331 |
|
|
DAY = MOD(NYMD,100) |
332 |
|
|
|
333 |
|
|
IDAY = MNDY( MONTH ,MOD(YEAR ,4)+1 ) |
334 |
|
|
month = month + nsegm |
335 |
|
|
If( month.gt.12 ) then |
336 |
|
|
month = month - 12 |
337 |
|
|
year = year + 1 |
338 |
|
|
endif |
339 |
|
|
IDAY2 = MNDY( MONTH ,MOD(YEAR ,4)+1 ) |
340 |
|
|
|
341 |
|
|
nday = iday2-iday |
342 |
|
|
if(nday.lt.0) nday = nday + 1461 |
343 |
|
|
nday = nday + nsegd |
344 |
|
|
|
345 |
|
|
nsecf2 = nsecf2 + nday*nsday |
346 |
|
|
|
347 |
|
|
return |
348 |
|
|
end |
349 |
|
|
|
350 |
|
|
subroutine fixdate (nymd) |
351 |
|
|
implicit none |
352 |
|
|
integer nymd |
353 |
|
|
|
354 |
|
|
c Modify 6-digit YYMMDD for dates between 1950-2050 |
355 |
|
|
c ------------------------------------------------- |
356 |
|
|
if (nymd .lt. 500101) then |
357 |
|
|
nymd = 20000000 + nymd |
358 |
|
|
else if (nymd .le. 991231) then |
359 |
|
|
nymd = 19000000 + nymd |
360 |
|
|
endif |
361 |
|
|
|
362 |
|
|
return |
363 |
|
|
end |
364 |
|
|
|
365 |
|
|
subroutine interp_time ( nymd ,nhms , |
366 |
|
|
. nymd1,nhms1, nymd2,nhms2, fac1,fac2 ) |
367 |
|
|
C*********************************************************************** |
368 |
|
|
C |
369 |
|
|
C PURPOSE: |
370 |
|
|
C ======== |
371 |
|
|
C Compute interpolation factors, fac1 & fac2, to be used in the |
372 |
|
|
C calculation of the instantanious boundary conditions, ie: |
373 |
|
|
C |
374 |
|
|
C q(i,j) = fac1*q1(i,j) + fac2*q2(i,j) |
375 |
|
|
C where: |
376 |
|
|
C q(i,j) => Boundary Data valid at (nymd , nhms ) |
377 |
|
|
C q1(i,j) => Boundary Data centered at (nymd1 , nhms1) |
378 |
|
|
C q2(i,j) => Boundary Data centered at (nymd2 , nhms2) |
379 |
|
|
C |
380 |
|
|
C INPUT: |
381 |
|
|
C ====== |
382 |
|
|
C nymd : Date (yymmdd) of Current Timestep |
383 |
|
|
C nhms : Time (hhmmss) of Current Timestep |
384 |
|
|
C nymd1 : Date (yymmdd) of Boundary Data 1 |
385 |
|
|
C nhms1 : Time (hhmmss) of Boundary Data 1 |
386 |
|
|
C nymd2 : Date (yymmdd) of Boundary Data 2 |
387 |
|
|
C nhms2 : Time (hhmmss) of Boundary Data 2 |
388 |
|
|
C |
389 |
|
|
C OUTPUT: |
390 |
|
|
C ======= |
391 |
|
|
C fac1 : Interpolation factor for Boundary Data 1 |
392 |
|
|
C fac2 : Interpolation factor for Boundary Data 2 |
393 |
|
|
C |
394 |
|
|
C |
395 |
|
|
C*********************************************************************** |
396 |
|
|
implicit none |
397 |
|
|
|
398 |
|
|
integer nhms,nymd,nhms1,nymd1,nhms2,nymd2 |
399 |
|
|
_RL fac1,fac2 |
400 |
|
|
|
401 |
|
|
INTEGER YEAR , MONTH , DAY , SEC |
402 |
|
|
INTEGER YEAR1, MONTH1, DAY1, SEC1 |
403 |
|
|
INTEGER YEAR2, MONTH2, DAY2, SEC2 |
404 |
|
|
|
405 |
|
|
_RL time, time1, time2 |
406 |
|
|
|
407 |
|
|
INTEGER DAYSCY |
408 |
|
|
PARAMETER (DAYSCY = 365*4+1) |
409 |
|
|
|
410 |
|
|
INTEGER MNDY(12,4) |
411 |
|
|
|
412 |
|
|
LOGICAL FIRST |
413 |
|
|
DATA FIRST/.TRUE./ |
414 |
|
|
|
415 |
|
|
DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366, |
416 |
|
|
. 397,34*0 / |
417 |
|
|
|
418 |
|
|
integer i,nsecf |
419 |
|
|
|
420 |
|
|
C*********************************************************************** |
421 |
|
|
C* SET TIME BOUNDARIES * |
422 |
|
|
C*********************************************************************** |
423 |
|
|
|
424 |
|
|
YEAR = NYMD / 10000 |
425 |
|
|
MONTH = MOD(NYMD,10000) / 100 |
426 |
|
|
DAY = MOD(NYMD,100) |
427 |
|
|
SEC = NSECF(NHMS) |
428 |
|
|
|
429 |
|
|
YEAR1 = NYMD1 / 10000 |
430 |
|
|
MONTH1 = MOD(NYMD1,10000) / 100 |
431 |
|
|
DAY1 = MOD(NYMD1,100) |
432 |
|
|
SEC1 = NSECF(NHMS1) |
433 |
|
|
|
434 |
|
|
YEAR2 = NYMD2 / 10000 |
435 |
|
|
MONTH2 = MOD(NYMD2,10000) / 100 |
436 |
|
|
DAY2 = MOD(NYMD2,100) |
437 |
|
|
SEC2 = NSECF(NHMS2) |
438 |
|
|
|
439 |
|
|
C*********************************************************************** |
440 |
|
|
C* COMPUTE DAYS IN 4-YEAR CYCLE * |
441 |
|
|
C*********************************************************************** |
442 |
|
|
|
443 |
|
|
IF(FIRST) THEN |
444 |
|
|
DO I=15,48 |
445 |
|
|
MNDY(I,1) = MNDY(I-12,1) + 365 |
446 |
|
|
ENDDO |
447 |
|
|
FIRST=.FALSE. |
448 |
|
|
ENDIF |
449 |
|
|
|
450 |
|
|
C*********************************************************************** |
451 |
|
|
C* COMPUTE INTERPOLATION FACTORS * |
452 |
|
|
C*********************************************************************** |
453 |
|
|
|
454 |
|
|
time = DAY + MNDY(MONTH ,MOD(YEAR ,4)+1) + float(sec )/86400. |
455 |
|
|
time1 = DAY1 + MNDY(MONTH1,MOD(YEAR1,4)+1) + float(sec1)/86400. |
456 |
|
|
time2 = DAY2 + MNDY(MONTH2,MOD(YEAR2,4)+1) + float(sec2)/86400. |
457 |
|
|
|
458 |
|
|
if( time .lt.time1 ) time = time + dayscy |
459 |
|
|
if( time2.lt.time1 ) time2 = time2 + dayscy |
460 |
|
|
|
461 |
|
|
fac1 = (time2-time)/(time2-time1) |
462 |
|
|
fac2 = (time-time1)/(time2-time1) |
463 |
|
|
|
464 |
|
|
RETURN |
465 |
|
|
END |
466 |
|
|
|
467 |
|
|
subroutine tick (nymd,nhms,ndt) |
468 |
|
|
C*********************************************************************** |
469 |
|
|
C Purpose |
470 |
|
|
C Tick the Date (nymd) and Time (nhms) by NDT (seconds) |
471 |
|
|
C |
472 |
|
|
C*********************************************************************** |
473 |
|
|
implicit none |
474 |
|
|
|
475 |
|
|
integer nymd,nhms,ndt |
476 |
|
|
|
477 |
|
|
integer nsec,nsecf,incymd,nhmsf |
478 |
|
|
|
479 |
|
|
IF(NDT.NE.0) THEN |
480 |
|
|
NSEC = NSECF(NHMS) + NDT |
481 |
|
|
|
482 |
|
|
IF (NSEC.GT.86400) THEN |
483 |
|
|
DO WHILE (NSEC.GT.86400) |
484 |
|
|
NSEC = NSEC - 86400 |
485 |
|
|
NYMD = INCYMD (NYMD,1) |
486 |
|
|
ENDDO |
487 |
|
|
ENDIF |
488 |
|
|
|
489 |
|
|
IF (NSEC.EQ.86400) THEN |
490 |
|
|
NSEC = 0 |
491 |
|
|
NYMD = INCYMD (NYMD,1) |
492 |
|
|
ENDIF |
493 |
|
|
|
494 |
|
|
IF (NSEC.LT.00000) THEN |
495 |
|
|
DO WHILE (NSEC.LT.0) |
496 |
|
|
NSEC = 86400 + NSEC |
497 |
|
|
NYMD = INCYMD (NYMD,-1) |
498 |
|
|
ENDDO |
499 |
|
|
ENDIF |
500 |
|
|
|
501 |
|
|
NHMS = NHMSF (NSEC) |
502 |
|
|
ENDIF |
503 |
|
|
|
504 |
|
|
RETURN |
505 |
|
|
END |
506 |
|
|
|
507 |
|
|
subroutine tic_time (mymd,mhms,ndt) |
508 |
|
|
C*********************************************************************** |
509 |
|
|
C PURPOSE |
510 |
|
|
C Tick the Clock by NDT (seconds) |
511 |
|
|
C |
512 |
|
|
C*********************************************************************** |
513 |
|
|
implicit none |
514 |
|
|
#include "chronos.h" |
515 |
|
|
|
516 |
|
|
integer mymd,mhms,ndt |
517 |
|
|
|
518 |
|
|
integer nsec,nsecf,incymd,nhmsf |
519 |
|
|
|
520 |
|
|
IF(NDT.NE.0) THEN |
521 |
|
|
NSEC = NSECF(NHMS) + NDT |
522 |
|
|
|
523 |
|
|
IF (NSEC.GT.86400) THEN |
524 |
|
|
DO WHILE (NSEC.GT.86400) |
525 |
|
|
NSEC = NSEC - 86400 |
526 |
|
|
NYMD = INCYMD (NYMD,1) |
527 |
|
|
ENDDO |
528 |
|
|
ENDIF |
529 |
|
|
|
530 |
|
|
IF (NSEC.EQ.86400) THEN |
531 |
|
|
NSEC = 0 |
532 |
|
|
NYMD = INCYMD (NYMD,1) |
533 |
|
|
ENDIF |
534 |
|
|
|
535 |
|
|
IF (NSEC.LT.00000) THEN |
536 |
|
|
DO WHILE (NSEC.LT.0) |
537 |
|
|
NSEC = 86400 + NSEC |
538 |
|
|
NYMD = INCYMD (NYMD,-1) |
539 |
|
|
ENDDO |
540 |
|
|
ENDIF |
541 |
|
|
|
542 |
|
|
NHMS = NHMSF (NSEC) |
543 |
|
|
ENDIF |
544 |
|
|
|
545 |
|
|
c Pass Back Current Updated Time |
546 |
|
|
c ------------------------------ |
547 |
|
|
mymd = nymd |
548 |
|
|
mhms = nhms |
549 |
|
|
|
550 |
|
|
RETURN |
551 |
|
|
END |
552 |
|
|
|
553 |
|
|
FUNCTION NALARM (MHMS,NYMD,NHMS,NYMD0,NHMS0) |
554 |
|
|
C*********************************************************************** |
555 |
|
|
C PURPOSE |
556 |
|
|
C COMPUTES MODULO-FRACTION BETWEEN MHHS AND TOTAL TIME |
557 |
|
|
C USAGE |
558 |
|
|
C ARGUMENTS DESCRIPTION |
559 |
|
|
C MHMS INTERVAL FREQUENCY (HHMMSS) |
560 |
|
|
C NYMD CURRENT YYMMDD |
561 |
|
|
C NHMS CURRENT HHMMSS |
562 |
|
|
C NYMD0 BEGINNING YYMMDD |
563 |
|
|
C NHMS0 BEGINNING HHMMSS |
564 |
|
|
C |
565 |
|
|
C*********************************************************************** |
566 |
|
|
implicit none |
567 |
|
|
|
568 |
|
|
integer nalarm,MHMS,NYMD,NHMS,NYMD0,NHMS0 |
569 |
|
|
|
570 |
|
|
integer nsday, ncycle |
571 |
|
|
PARAMETER ( NSDAY = 86400 ) |
572 |
|
|
PARAMETER ( NCYCLE = 1461*24*3600 ) |
573 |
|
|
|
574 |
|
|
INTEGER YEAR, MONTH, DAY, SEC, YEAR0, MONTH0, DAY0, SEC0 |
575 |
|
|
|
576 |
|
|
integer MNDY(12,4) |
577 |
|
|
DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366, |
578 |
|
|
. 397,34*0 / |
579 |
|
|
|
580 |
|
|
integer i,nsecf,iday,iday0,nsec,nsec0,ntime |
581 |
|
|
|
582 |
|
|
C*********************************************************************** |
583 |
|
|
C* COMPUTE # OF DAYS IN A 4-YEAR CYCLE * |
584 |
|
|
C*********************************************************************** |
585 |
|
|
|
586 |
|
|
DO I=15,48 |
587 |
|
|
MNDY(I,1) = MNDY(I-12,1) + 365 |
588 |
|
|
ENDDO |
589 |
|
|
|
590 |
|
|
C*********************************************************************** |
591 |
|
|
C* SET CURRENT AND BEGINNING TIMES * |
592 |
|
|
C*********************************************************************** |
593 |
|
|
|
594 |
|
|
YEAR = NYMD / 10000 |
595 |
|
|
MONTH = MOD(NYMD,10000) / 100 |
596 |
|
|
DAY = MOD(NYMD,100) |
597 |
|
|
SEC = NSECF(NHMS) |
598 |
|
|
|
599 |
|
|
YEAR0 = NYMD0 / 10000 |
600 |
|
|
MONTH0 = MOD(NYMD0,10000) / 100 |
601 |
|
|
DAY0 = MOD(NYMD0,100) |
602 |
|
|
SEC0 = NSECF(NHMS0) |
603 |
|
|
|
604 |
|
|
C*********************************************************************** |
605 |
|
|
C* COMPUTE POSITIONS IN CYCLE FOR CURRENT AND BEGINNING TIMES * |
606 |
|
|
C*********************************************************************** |
607 |
|
|
|
608 |
|
|
IDAY = (DAY -1) + MNDY( MONTH ,MOD(YEAR ,4)+1 ) |
609 |
|
|
IDAY0 = (DAY0-1) + MNDY( MONTH0,MOD(YEAR0,4)+1 ) |
610 |
|
|
|
611 |
|
|
NSEC = IDAY *NSDAY + SEC |
612 |
|
|
NSEC0 = IDAY0*NSDAY + SEC0 |
613 |
|
|
|
614 |
|
|
NTIME = NSEC-NSEC0 |
615 |
|
|
IF (NTIME.LT.0 ) NTIME = NTIME + NCYCLE |
616 |
|
|
NALARM = NTIME |
617 |
|
|
IF ( MHMS.NE.0 ) NALARM = MOD( NALARM,NSECF(MHMS) ) |
618 |
|
|
|
619 |
|
|
RETURN |
620 |
|
|
END |
621 |
|
|
|
622 |
|
|
FUNCTION INCYMD (NYMD,M) |
623 |
|
|
C*********************************************************************** |
624 |
|
|
C PURPOSE |
625 |
|
|
C INCYMD: NYMD CHANGED BY ONE DAY |
626 |
|
|
C MODYMD: NYMD CONVERTED TO JULIAN DATE |
627 |
|
|
C DESCRIPTION OF PARAMETERS |
628 |
|
|
C NYMD CURRENT DATE IN YYMMDD FORMAT |
629 |
|
|
C M +/- 1 (DAY ADJUSTMENT) |
630 |
|
|
C |
631 |
|
|
C*********************************************************************** |
632 |
|
|
implicit none |
633 |
|
|
integer incymd,nymd,m |
634 |
|
|
|
635 |
|
|
integer ny,nm,nd,ny00,modymd |
636 |
|
|
|
637 |
|
|
INTEGER NDPM(12) |
638 |
|
|
DATA NDPM /31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/ |
639 |
|
|
LOGICAL LEAP |
640 |
|
|
DATA NY00 /1900 / |
641 |
|
|
LEAP(NY) = MOD(NY,4).EQ.0 .AND. (NY.NE.0 .OR. MOD(NY00,400).EQ.0) |
642 |
|
|
|
643 |
|
|
C*********************************************************************** |
644 |
|
|
C |
645 |
|
|
NY = NYMD / 10000 |
646 |
|
|
NM = MOD(NYMD,10000) / 100 |
647 |
|
|
ND = MOD(NYMD,100) + M |
648 |
|
|
|
649 |
|
|
IF (ND.EQ.0) THEN |
650 |
|
|
NM = NM - 1 |
651 |
|
|
IF (NM.EQ.0) THEN |
652 |
|
|
NM = 12 |
653 |
|
|
NY = NY - 1 |
654 |
|
|
ENDIF |
655 |
|
|
ND = NDPM(NM) |
656 |
|
|
IF (NM.EQ.2 .AND. LEAP(NY)) ND = 29 |
657 |
|
|
ENDIF |
658 |
|
|
|
659 |
|
|
IF (ND.EQ.29 .AND. NM.EQ.2 .AND. LEAP(NY)) GO TO 20 |
660 |
|
|
|
661 |
|
|
IF (ND.GT.NDPM(NM)) THEN |
662 |
|
|
ND = 1 |
663 |
|
|
NM = NM + 1 |
664 |
|
|
IF (NM.GT.12) THEN |
665 |
|
|
NM = 1 |
666 |
|
|
NY = NY + 1 |
667 |
|
|
ENDIF |
668 |
|
|
ENDIF |
669 |
|
|
|
670 |
|
|
20 CONTINUE |
671 |
|
|
INCYMD = NY*10000 + NM*100 + ND |
672 |
|
|
|
673 |
|
|
RETURN |
674 |
|
|
|
675 |
|
|
C*********************************************************************** |
676 |
|
|
C E N T R Y M O D Y M D |
677 |
|
|
C*********************************************************************** |
678 |
|
|
|
679 |
|
|
ENTRY MODYMD (NYMD) |
680 |
|
|
|
681 |
|
|
NY = NYMD / 10000 |
682 |
|
|
NM = MOD(NYMD,10000) / 100 |
683 |
|
|
ND = MOD(NYMD,100) |
684 |
|
|
|
685 |
|
|
40 CONTINUE |
686 |
|
|
IF (NM.LE.1) GO TO 60 |
687 |
|
|
NM = NM - 1 |
688 |
|
|
ND = ND + NDPM(NM) |
689 |
|
|
IF (NM.EQ.2 .AND. LEAP(NY)) ND = ND + 1 |
690 |
|
|
GO TO 40 |
691 |
|
|
|
692 |
|
|
60 CONTINUE |
693 |
|
|
MODYMD = ND |
694 |
|
|
|
695 |
|
|
RETURN |
696 |
|
|
END |
697 |
|
|
|
698 |
|
|
SUBROUTINE ASTRO ( NYMD,NHMS,ALAT,ALON,IRUN,COSZ,RA ) |
699 |
|
|
C*********************************************************************** |
700 |
|
|
C |
701 |
|
|
C INPUT: |
702 |
|
|
C ====== |
703 |
|
|
C NYMD : CURRENT YYMMDD |
704 |
|
|
C NHMS : CURRENT HHMMSS |
705 |
|
|
C ALAT(IRUN):LATITUDES IN DEGREES. |
706 |
|
|
C ALON(IRUN):LONGITUDES IN DEGREES. (0 = GREENWICH, + = EAST). |
707 |
|
|
C IRUN : # OF POINTS TO CALCULATE |
708 |
|
|
C |
709 |
|
|
C OUTPUT: |
710 |
|
|
C ======= |
711 |
|
|
C COSZ(IRUN) : COSINE OF ZENITH ANGLE. |
712 |
|
|
C RA : EARTH-SUN DISTANCE IN UNITS OF |
713 |
|
|
C THE ORBITS SEMI-MAJOR AXIS. |
714 |
|
|
C |
715 |
|
|
C NOTE: |
716 |
|
|
C ===== |
717 |
|
|
C THE INSOLATION AT THE TOP OF THE ATMOSPHERE IS: |
718 |
|
|
C |
719 |
|
|
C S(I) = (SOLAR CONSTANT)*(1/RA**2)*COSZ(I), |
720 |
|
|
C |
721 |
|
|
C WHERE: |
722 |
|
|
C RA AND COSZ(I) ARE THE TWO OUTPUTS OF THIS SUBROUTINE. |
723 |
|
|
C |
724 |
|
|
C*********************************************************************** |
725 |
|
|
|
726 |
|
|
implicit none |
727 |
|
|
|
728 |
|
|
c Input Variables |
729 |
|
|
c --------------- |
730 |
|
|
integer nymd, nhms, irun |
731 |
|
|
_RL cosz(irun), alat(irun), alon(irun), ra |
732 |
|
|
|
733 |
|
|
c Local Variables |
734 |
|
|
c --------------- |
735 |
|
|
integer year, day, sec, month, iday, idayp1 |
736 |
|
|
integer dayscy |
737 |
|
|
integer i,nsecf,k,km,kp |
738 |
|
|
|
739 |
|
|
_RL hc |
740 |
|
|
_RL pi, zero, one, two, six, dg2rd, yrlen, eqnx, ob, ecc, per |
741 |
|
|
_RL daylen, fac, thm, thp, thnow, zs, zc, sj, cj |
742 |
|
|
|
743 |
|
|
parameter ( pi = 3.1415926535898) |
744 |
|
|
parameter ( zero = 0.0 ) |
745 |
|
|
parameter ( one = 1.0 ) |
746 |
|
|
parameter ( two = 2.0 ) |
747 |
|
|
parameter ( six = 6.0 ) |
748 |
|
|
parameter ( dg2rd = pi/180. ) |
749 |
|
|
|
750 |
|
|
parameter ( yrlen = 365.25 ) |
751 |
|
|
parameter ( dayscy = 365*4+1 ) |
752 |
|
|
parameter ( eqnx = 80.9028) |
753 |
|
|
parameter ( ob = 23.45*dg2rd ) |
754 |
|
|
parameter ( ecc = 0.0167 ) |
755 |
|
|
parameter ( per = 102.0*dg2rd) |
756 |
|
|
parameter ( daylen = 86400.) |
757 |
|
|
|
758 |
|
|
_RL TH(DAYSCY),T0,T1,T2,T3,T4,FUN,Y,MNDY(12,4) |
759 |
|
|
|
760 |
|
|
LOGICAL FIRST |
761 |
|
|
DATA FIRST/.TRUE./ |
762 |
|
|
SAVE |
763 |
|
|
|
764 |
|
|
DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366, |
765 |
|
|
. 397,34*0 / |
766 |
|
|
|
767 |
|
|
FUN(Y) = (TWO*PI/((ONE-ECC**2)**1.5))*(ONE/YRLEN) |
768 |
|
|
. * (ONE - ECC*COS(Y-PER)) ** 2 |
769 |
|
|
|
770 |
|
|
C*********************************************************************** |
771 |
|
|
C* SET CURRENT TIME * |
772 |
|
|
C*********************************************************************** |
773 |
|
|
|
774 |
|
|
YEAR = NYMD / 10000 |
775 |
|
|
MONTH = MOD(NYMD,10000) / 100 |
776 |
|
|
DAY = MOD(NYMD,100) |
777 |
|
|
SEC = NSECF(NHMS) |
778 |
|
|
|
779 |
|
|
C*********************************************************************** |
780 |
|
|
C* COMPUTE DAY-ANGLES FOR 4-YEAR CYCLE * |
781 |
|
|
C*********************************************************************** |
782 |
|
|
|
783 |
|
|
IF(FIRST) THEN |
784 |
|
|
DO 100 I=15,48 |
785 |
|
|
MNDY(I,1) = MNDY(I-12,1) + 365 |
786 |
|
|
100 CONTINUE |
787 |
|
|
|
788 |
|
|
KM = INT(EQNX) + 1 |
789 |
|
|
FAC = KM-EQNX |
790 |
|
|
T0 = ZERO |
791 |
|
|
T1 = FUN(T0 )*FAC |
792 |
|
|
T2 = FUN(ZERO+T1/TWO)*FAC |
793 |
|
|
T3 = FUN(ZERO+T2/TWO)*FAC |
794 |
|
|
T4 = FUN(ZERO+T3 )*FAC |
795 |
|
|
TH(KM) = (T1 + TWO*(T2 + T3) + T4) / SIX |
796 |
|
|
|
797 |
|
|
DO 200 K=2,DAYSCY |
798 |
|
|
T1 = FUN(TH(KM) ) |
799 |
|
|
T2 = FUN(TH(KM)+T1/TWO) |
800 |
|
|
T3 = FUN(TH(KM)+T2/TWO) |
801 |
|
|
T4 = FUN(TH(KM)+T3 ) |
802 |
|
|
KP = MOD(KM,DAYSCY) + 1 |
803 |
|
|
TH(KP) = TH(KM) + (T1 + TWO*(T2 + T3) + T4) / SIX |
804 |
|
|
KM = KP |
805 |
|
|
200 CONTINUE |
806 |
|
|
|
807 |
|
|
FIRST=.FALSE. |
808 |
|
|
ENDIF |
809 |
|
|
|
810 |
|
|
C*********************************************************************** |
811 |
|
|
C* COMPUTE EARTH-SUN DISTANCE TO CURRENT SECOND * |
812 |
|
|
C*********************************************************************** |
813 |
|
|
|
814 |
|
|
IDAY = DAY + MNDY(MONTH,MOD(YEAR,4)+1) |
815 |
|
|
IDAYP1 = MOD( IDAY,DAYSCY) + 1 |
816 |
|
|
THM = MOD( TH(IDAY) ,TWO*PI) |
817 |
|
|
THP = MOD( TH(IDAYP1),TWO*PI) |
818 |
|
|
|
819 |
|
|
IF(THP.LT.THM) THP = THP + TWO*PI |
820 |
|
|
FAC = FLOAT(SEC)/DAYLEN |
821 |
|
|
THNOW = THM*(ONE-FAC) + THP*FAC |
822 |
|
|
|
823 |
|
|
ZS = SIN(THNOW) * SIN(OB) |
824 |
|
|
ZC = SQRT(ONE-ZS*ZS) |
825 |
|
|
RA = (1.-ECC*ECC) / ( ONE-ECC*COS(THNOW-PER) ) |
826 |
|
|
|
827 |
|
|
C*********************************************************************** |
828 |
|
|
C* COMPUTE COSINE OF THE ZENITH ANGLE * |
829 |
|
|
C*********************************************************************** |
830 |
|
|
|
831 |
|
|
FAC = FAC*TWO*PI + PI |
832 |
|
|
DO I = 1,IRUN |
833 |
|
|
|
834 |
|
|
HC = COS( FAC+ALON(I)*DG2RD ) |
835 |
|
|
SJ = SIN(ALAT(I)*DG2RD) |
836 |
|
|
CJ = SQRT(ONE-SJ*SJ) |
837 |
|
|
|
838 |
|
|
COSZ(I) = SJ*ZS + CJ*ZC*HC |
839 |
|
|
IF( COSZ(I).LT.ZERO ) COSZ(I) = ZERO |
840 |
|
|
ENDDO |
841 |
|
|
|
842 |
|
|
RETURN |
843 |
|
|
END |
844 |
|
|
|
845 |
|
|
subroutine time_bound(nymd,nhms,nymd1,nhms1,nymd2,nhms2,imnm,imnp) |
846 |
|
|
C*********************************************************************** |
847 |
|
|
C PURPOSE |
848 |
|
|
C Compute Date and Time boundaries. |
849 |
|
|
C |
850 |
|
|
C ARGUMENTS DESCRIPTION |
851 |
|
|
C nymd .... Current Date |
852 |
|
|
C nhms .... Current Time |
853 |
|
|
C nymd1 ... Previous Date Boundary |
854 |
|
|
C nhms1 ... Previous Time Boundary |
855 |
|
|
C nymd2 ... Subsequent Date Boundary |
856 |
|
|
C nhms2 ... Subsequent Time Boundary |
857 |
|
|
C |
858 |
|
|
C imnm .... Previous Time Index for Interpolation |
859 |
|
|
C imnp .... Subsequent Time Index for Interpolation |
860 |
|
|
C |
861 |
|
|
C*********************************************************************** |
862 |
|
|
|
863 |
|
|
implicit none |
864 |
|
|
integer nymd,nhms, nymd1,nhms1, nymd2,nhms2 |
865 |
|
|
|
866 |
|
|
c Local Variables |
867 |
|
|
c --------------- |
868 |
|
|
integer month,day,nyear,midmon1,midmon,midmon2 |
869 |
|
|
integer imnm,imnp |
870 |
|
|
INTEGER DAYS(14), daysm, days0, daysp |
871 |
|
|
DATA DAYS /31,31,28,31,30,31,30,31,31,30,31,30,31,31/ |
872 |
|
|
|
873 |
|
|
integer nmonf,ndayf,n |
874 |
|
|
NMONF(N) = MOD(N,10000)/100 |
875 |
|
|
NDAYF(N) = MOD(N,100) |
876 |
|
|
|
877 |
|
|
C********************************************************************* |
878 |
|
|
C**** Find Proper Month and Time Boundaries for Climatological Data ** |
879 |
|
|
C********************************************************************* |
880 |
|
|
|
881 |
|
|
MONTH = NMONF(NYMD) |
882 |
|
|
DAY = NDAYF(NYMD) |
883 |
|
|
|
884 |
|
|
daysm = days(month ) |
885 |
|
|
days0 = days(month+1) |
886 |
|
|
daysp = days(month+2) |
887 |
|
|
|
888 |
|
|
c Check for Leap Year |
889 |
|
|
c ------------------- |
890 |
|
|
nyear = nymd/10000 |
891 |
|
|
if( 4*(nyear/4).eq.nyear ) then |
892 |
|
|
if( month.eq.3 ) daysm = daysm+1 |
893 |
|
|
if( month.eq.2 ) days0 = days0+1 |
894 |
|
|
if( month.eq.1 ) daysp = daysp+1 |
895 |
|
|
endif |
896 |
|
|
|
897 |
|
|
MIDMON1 = daysm/2 + 1 |
898 |
|
|
MIDMON = days0/2 + 1 |
899 |
|
|
MIDMON2 = daysp/2 + 1 |
900 |
|
|
|
901 |
|
|
|
902 |
|
|
IF(DAY.LT.MIDMON) THEN |
903 |
|
|
imnm = month |
904 |
|
|
imnp = month + 1 |
905 |
|
|
nymd2 = (nymd/10000)*10000 + month*100 + midmon |
906 |
|
|
nhms2 = 000000 |
907 |
|
|
nymd1 = nymd2 |
908 |
|
|
nhms1 = nhms2 |
909 |
|
|
call tick ( nymd1,nhms1, -midmon *86400 ) |
910 |
|
|
call tick ( nymd1,nhms1,-(daysm-midmon1)*86400 ) |
911 |
|
|
ELSE |
912 |
|
|
IMNM = MONTH + 1 |
913 |
|
|
IMNP = MONTH + 2 |
914 |
|
|
nymd1 = (nymd/10000)*10000 + month*100 + midmon |
915 |
|
|
nhms1 = 000000 |
916 |
|
|
nymd2 = nymd1 |
917 |
|
|
nhms2 = nhms1 |
918 |
|
|
call tick ( nymd2,nhms2,(days0-midmon)*86400 ) |
919 |
|
|
call tick ( nymd2,nhms2, midmon2*86400 ) |
920 |
|
|
ENDIF |
921 |
|
|
|
922 |
|
|
c ------------------------------------------------------------- |
923 |
|
|
c Note: At this point, imnm & imnp range between 01-14, where |
924 |
|
|
c 01 -> Previous years December |
925 |
|
|
c 02-13 -> Current years January-December |
926 |
|
|
c 14 -> Next years January |
927 |
|
|
c ------------------------------------------------------------- |
928 |
|
|
|
929 |
|
|
imnm = imnm-1 |
930 |
|
|
imnp = imnp-1 |
931 |
|
|
|
932 |
|
|
if( imnm.eq.0 ) imnm = 12 |
933 |
|
|
if( imnp.eq.0 ) imnp = 12 |
934 |
|
|
if( imnm.eq.13 ) imnm = 1 |
935 |
|
|
if( imnp.eq.13 ) imnp = 1 |
936 |
|
|
|
937 |
|
|
return |
938 |
|
|
end |