/[MITgcm]/MITgcm/pkg/fizhi/fizhi_clockstuff.F
ViewVC logotype

Contents of /MITgcm/pkg/fizhi/fizhi_clockstuff.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.31 - (show annotations) (download)
Thu Mar 22 14:22:32 2012 UTC (12 years, 3 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint64y, checkpoint64x, checkpoint64z, checkpoint64q, checkpoint64p, checkpoint64s, checkpoint64r, checkpoint64u, checkpoint64t, checkpoint64w, checkpoint64v, checkpoint64i, checkpoint64h, checkpoint64k, checkpoint64j, checkpoint64m, checkpoint64l, checkpoint64o, checkpoint64n, checkpoint64a, checkpoint64c, checkpoint64b, checkpoint64e, checkpoint64d, checkpoint64g, checkpoint64f, checkpoint63p, checkpoint63q, checkpoint63r, checkpoint63s, checkpoint63l, checkpoint63m, checkpoint63n, checkpoint63o, checkpoint64, checkpoint65, checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, checkpoint65z, checkpoint65x, checkpoint65y, checkpoint65r, checkpoint65s, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint65j, checkpoint65k, checkpoint65h, checkpoint65i, checkpoint65n, checkpoint65o, checkpoint65l, checkpoint65m, checkpoint65b, checkpoint65c, checkpoint65a, checkpoint65f, checkpoint65g, checkpoint65d, checkpoint65e, HEAD
Changes since 1.30: +27 -17 lines
in S/R SET_ALARM, print msg to STDOUT (cleaner if using  MPI)

1 C $Header: /u/gcmpack/MITgcm/pkg/fizhi/fizhi_clockstuff.F,v 1.30 2012/03/19 21:46:58 jmc Exp $
2 C $Name: $
3
4 #include "FIZHI_OPTIONS.h"
5
6 C-- File fizhi_clockstuff.F:
7 C-- Contents
8 C-- o SET_ALARM
9 C-- o GET_ALARM
10 C-- o ALARM (function)
11 C-- o ALARM2 (function)
12 C-- o ALARM2NEXT (function)
13 C-- o SET_TIME
14 C-- o GET_TIME
15 C-- o NSECF (function)
16 C-- o NHMSF (function)
17 C-- o NSECF2 (function)
18 C-- o FIXDATE
19 C-- o INTERP_TIME
20 C-- o TICK
21 C-- o TIC_TIME
22 C-- o NALARM (function)
23 C-- o NALARM2 (function)
24 C-- o INCYMD (function)
25 C-- o ASTRO
26 C-- o TIME_BOUND
27 C-- o TIME2FREQ2
28
29 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
30
31 subroutine set_alarm (tag,datein,timein,freq)
32 C***********************************************************************
33 C Purpose
34 C -------
35 C Utility to Set Internal Alarms
36 C
37 C Argument Description
38 C --------------------
39 C tag ....... Character String Tagging Alarm Process
40 C date ...... Begining Date for Alarm
41 C time ...... Begining Time for Alarm
42 C freq ...... Repeating Frequency Interval for Alarm
43 C
44 C***********************************************************************
45
46 implicit none
47 #include "EEPARAMS.h"
48 #include "chronos.h"
49
50 character*(*) tag
51 integer freq,datein,timein
52
53 C- functions:
54 INTEGER ILNBLNK
55 EXTERNAL ILNBLNK
56
57 C- local variables:
58 integer myid
59 logical first,set
60 data first /.true./
61 integer n, iL
62
63 myid = 1
64 if(first) then
65 ntags = 1
66 tags(1) = tag
67 freqs(1) = freq
68 dates(1) = datein
69 times(1) = timein
70 iL = ILNBLNK(tag)
71 WRITE(standardMessageUnit,'(A,I8,A,I6.6,A,I10,2A)')
72 & ' Set Alarm for: ', datein, ' ', timein,
73 & ', with frequency: ', freq, ', and Tag: ',tag(1:iL)
74 else
75
76 set = .false.
77 do n=1,ntags
78 if(tag.eq.tags(n)) then
79 if( myid.eq.1 ) then
80 print *, 'Warning! Alarm has already been set for Tag: ',tag
81 print *, 'Changing Alarm Information:'
82 print *, 'Frequency: ',freqs(n),' (Old) ',freq,' (New)'
83 print *, ' Date0: ',dates(n),' (Old) ',datein,' (New)'
84 print *, ' Time0: ',times(n),' (Old) ',timein,' (New)'
85 endif
86 freqs(n) = freq
87 dates(n) = datein
88 times(n) = timein
89 set = .true.
90 endif
91 enddo
92 if(.not.set) then
93 ntags = ntags+1
94 if(ntags.gt.maxtag ) then
95 if( myid.eq.1 ) then
96 print *, 'Too many Alarms are Set!!'
97 print *, 'Maximum Number of Alarms = ',maxtag
98 endif
99 call my_finalize
100 call my_exit (101)
101 endif
102 tags(ntags) = tag
103 freqs(ntags) = freq
104 dates(ntags) = datein
105 times(ntags) = timein
106 iL = ILNBLNK(tag)
107 WRITE(standardMessageUnit,'(A,I8,A,I6.6,A,I10,2A)')
108 & ' Set Alarm for: ', datein, ' ', timein,
109 & ', with frequency: ', freq, ', and Tag: ',tag(1:iL)
110 endif
111 endif
112
113 first = .false.
114 return
115 end
116
117 subroutine get_alarm (tag,datein,timein,freq,tleft)
118 C***********************************************************************
119 C Purpose
120 C -------
121 C Utility to Get Internal Alarm Information
122 C
123 C Input
124 C -----
125 C tag ....... Character String Tagging Alarm Process
126 C
127 C Output
128 C ------
129 C datein ...... Begining Date for Alarm
130 C timein ...... Begining Time for Alarm
131 C freq ........ Frequency Interval for Alarm
132 C tleft ....... Time Remaining (seconds) before Alarm is TRUE
133 C
134 C***********************************************************************
135
136 implicit none
137 character*(*) tag
138 integer freq,datein,timein,tleft
139
140 #include "chronos.h"
141
142 logical set,alarm
143 external alarm
144 integer myid,n,nalarm,nsecf
145
146 myid = 1
147 set = .false.
148 do n=1,ntags
149 if (tag.eq.tags(n)) then
150 freq = freqs(n)
151 datein = dates(n)
152 timein = times(n)
153
154 if ( alarm(tag) ) then
155 tleft = 0
156 else
157 call get_time (nymd,nhms)
158 tleft = nsecf(freq) - nalarm(freq,nymd,nhms,datein,timein )
159 endif
160
161 set = .true.
162 endif
163 enddo
164
165 if(.not.set) then
166 if( myid.eq.1 ) print *, 'Alarm has not been set for Tag: ',tag
167 freq = 0
168 datein = 0
169 timein = 0
170 tleft = 0
171 endif
172
173 return
174 end
175
176 LOGICAL FUNCTION ALARM (tag)
177 implicit none
178 character*(*) tag
179 #include "chronos.h"
180
181 integer datein,timein
182 integer n,nalarm
183 external nalarm
184
185 call get_time (datein,timein)
186
187 alarm = .false.
188 do n=1,ntags
189 if( tags(n).eq.tag ) then
190 if( freqs(n).eq.0 ) then
191 alarm = (dates(n).eq.datein) .and. (times(n).eq.timein)
192 else
193 alarm = ( datein.gt.dates(n) .or.
194 & (datein.eq.dates(n) .and. timein.ge.times(n)) )
195 & .and. nalarm( freqs(n),datein,timein,dates(n),times(n) ).eq.0
196 endif
197 endif
198 enddo
199
200 return
201 end
202
203 LOGICAL FUNCTION ALARM2 (tag)
204 implicit none
205 character*(*) tag
206 #include "chronos.h"
207
208 integer datein,timein
209 integer n,nalarm2
210 external nalarm2
211
212 call get_time (datein,timein)
213
214 alarm2 = .false.
215 do n=1,ntags
216 if( tags(n).eq.tag ) then
217 if( freqs(n).eq.0 ) then
218 alarm2 = (dates(n).eq.datein) .and. (times(n).eq.timein)
219 else
220 alarm2 = ( datein.gt.dates(n) .or.
221 & (datein.eq.dates(n) .and. timein.ge.times(n)) )
222 & .and. nalarm2( freqs(n),datein,timein,dates(n),times(n) ).eq.0
223 endif
224 endif
225 enddo
226
227 return
228 end
229
230 LOGICAL FUNCTION ALARM2NEXT (tag,deltat)
231 implicit none
232 character*(*) tag
233 _RL deltat
234 #include "chronos.h"
235
236 integer datein,timein,ndt
237 integer dateminus,timeminus
238 integer n,nalarm2
239 external nalarm2
240
241 ndt = int(deltat)
242 call get_time (dateminus,timeminus)
243 datein = dateminus
244 timein = timeminus
245 call tick(datein,timein,ndt)
246
247 alarm2next = .false.
248 do n=1,ntags
249 if( tags(n).eq.tag ) then
250 if( freqs(n).eq.0 ) then
251 alarm2next = (dates(n).eq.datein) .and. (times(n).eq.timein)
252 else
253 alarm2next = ( datein.gt.dates(n) .or.
254 & (datein.eq.dates(n) .and. timein.ge.times(n)) )
255 & .and. nalarm2( freqs(n),datein,timein,dates(n),times(n) ).eq.0
256 endif
257 endif
258 enddo
259
260 return
261 end
262
263 subroutine set_time (datein,timein)
264 implicit none
265 integer datein,timein
266
267 #include "chronos.h"
268
269 integer myid
270
271 myid = 1
272 if( myid.eq.1 ) then
273 print *, 'Setting Clock'
274 print *, 'Date: ',datein
275 print *, 'Time: ',timein
276 endif
277
278 nymd = datein
279 nhms = timein
280 return
281 end
282
283 subroutine get_time (datein,timein)
284 implicit none
285 integer datein,timein
286
287 #include "chronos.h"
288
289 datein = nymd
290 timein = nhms
291 return
292 end
293
294 function nsecf (nhms)
295 C***********************************************************************
296 C Purpose
297 C Converts NHMS format to Total Seconds
298 C
299 C***********************************************************************
300 implicit none
301 integer nhms, nsecf
302 nsecf = nhms/10000*3600 + mod(nhms,10000)/100*60 + mod(nhms,100)
303 return
304 end
305
306 function nhmsf (nsec)
307 C***********************************************************************
308 C Purpose
309 C Converts Total Seconds to NHMS format
310 C
311 C***********************************************************************
312 implicit none
313 integer nhmsf, nsec
314 nhmsf = nsec/3600*10000 + mod(nsec,3600)/60*100 + mod(nsec,60)
315 return
316 end
317
318 function nsecf2 (nhhmmss,nmmdd,nymd)
319 C***********************************************************************
320 C Purpose
321 C Computes the Total Number of seconds from NYMD using NHHMMSS & NMMDD
322 C
323 C Arguments Description
324 C NHHMMSS IntervaL Frequency (HHMMSS)
325 C NMMDD Interval Frequency (MMDD)
326 C NYMD Current Date (YYMMDD)
327 C
328 C NOTE:
329 C IF (NMMDD.ne.0), THEN HOUR FREQUENCY HH MUST BE < 24
330 C
331 C***********************************************************************
332 implicit none
333
334 integer nsecf2,nhhmmss,nmmdd,nymd
335
336 INTEGER NSDAY, NCYCLE
337 PARAMETER ( NSDAY = 86400 )
338 PARAMETER ( NCYCLE = 1461*24*3600 )
339
340 INTEGER YEAR, MONTH, DAY
341
342 c INTEGER MNDY(12,4)
343 INTEGER MNDY(12*4)
344 DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,
345 & 397,34*0 /
346
347 integer nsecf,i,nsegm,nsegd,iday,iday2,nday
348
349 C***********************************************************************
350 C* COMPUTE # OF SECONDS FROM NHHMMSS *
351 C***********************************************************************
352
353 nsecf2 = nsecf( nhhmmss )
354
355 if( nmmdd.eq.0 ) return
356
357 C***********************************************************************
358 C* COMPUTE # OF DAYS IN A 4-YEAR CYCLE *
359 C***********************************************************************
360
361 DO I=15,48
362 c MNDY(I,1) = MNDY(I-12,1) + 365
363 MNDY(I) = MNDY(I-12) + 365
364 ENDDO
365
366 C***********************************************************************
367 C* COMPUTE # OF SECONDS FROM NMMDD *
368 C***********************************************************************
369
370 nsegm = nmmdd/100
371 nsegd = mod(nmmdd,100)
372
373 YEAR = NYMD / 10000
374 MONTH = MOD(NYMD,10000) / 100
375 DAY = MOD(NYMD,100)
376
377 c IDAY = MNDY( MONTH ,MOD(YEAR ,4)+1 )
378 IDAY = MNDY( MONTH +12*MOD(YEAR ,4) )
379 month = month + nsegm
380 If( month.gt.12 ) then
381 month = month - 12
382 year = year + 1
383 endif
384 c IDAY2 = MNDY( MONTH ,MOD(YEAR ,4)+1 )
385 IDAY2 = MNDY( MONTH +12*MOD(YEAR ,4) )
386
387 nday = iday2-iday
388 if(nday.lt.0) nday = nday + 1461
389 nday = nday + nsegd
390
391 nsecf2 = nsecf2 + nday*nsday
392
393 return
394 end
395
396 subroutine fixdate (nymd)
397 implicit none
398 integer nymd
399
400 C Modify 6-digit YYMMDD for dates between 1950-2050
401 C -------------------------------------------------
402 if (nymd .lt. 500101) then
403 nymd = 20000000 + nymd
404 else if (nymd .le. 991231) then
405 nymd = 19000000 + nymd
406 endif
407
408 return
409 end
410
411 subroutine interp_time ( nymd ,nhms ,
412 & nymd1,nhms1, nymd2,nhms2, fac1,fac2 )
413 C***********************************************************************
414 C
415 C PURPOSE:
416 C ========
417 C Compute interpolation factors, fac1 & fac2, to be used in the
418 C calculation of the instantanious boundary conditions, ie:
419 C
420 C q(i,j) = fac1*q1(i,j) + fac2*q2(i,j)
421 C where:
422 C q(i,j) => Boundary Data valid at (nymd , nhms )
423 C q1(i,j) => Boundary Data centered at (nymd1 , nhms1)
424 C q2(i,j) => Boundary Data centered at (nymd2 , nhms2)
425 C
426 C INPUT:
427 C ======
428 C nymd : Date (yymmdd) of Current Timestep
429 C nhms : Time (hhmmss) of Current Timestep
430 C nymd1 : Date (yymmdd) of Boundary Data 1
431 C nhms1 : Time (hhmmss) of Boundary Data 1
432 C nymd2 : Date (yymmdd) of Boundary Data 2
433 C nhms2 : Time (hhmmss) of Boundary Data 2
434 C
435 C OUTPUT:
436 C =======
437 C fac1 : Interpolation factor for Boundary Data 1
438 C fac2 : Interpolation factor for Boundary Data 2
439 C
440 C
441 C***********************************************************************
442 implicit none
443
444 integer nhms,nymd,nhms1,nymd1,nhms2,nymd2
445 _RL fac1,fac2
446
447 INTEGER YEAR , MONTH , DAY , SEC
448 INTEGER YEAR1, MONTH1, DAY1, SEC1
449 INTEGER YEAR2, MONTH2, DAY2, SEC2
450
451 _RL time00, time1, time2
452
453 INTEGER DAYSCY
454 parameter ( dayscy = 365*4 + 1 )
455
456 INTEGER MNDY(12*4)
457
458 LOGICAL FIRST
459 DATA FIRST/.TRUE./
460
461 DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,
462 & 397,34*0 /
463
464 integer i,nsecf
465
466 C***********************************************************************
467 C* SET TIME BOUNDARIES *
468 C***********************************************************************
469
470 YEAR = NYMD / 10000
471 MONTH = MOD(NYMD,10000) / 100
472 DAY = MOD(NYMD,100)
473 SEC = NSECF(NHMS)
474
475 YEAR1 = NYMD1 / 10000
476 MONTH1 = MOD(NYMD1,10000) / 100
477 DAY1 = MOD(NYMD1,100)
478 SEC1 = NSECF(NHMS1)
479
480 YEAR2 = NYMD2 / 10000
481 MONTH2 = MOD(NYMD2,10000) / 100
482 DAY2 = MOD(NYMD2,100)
483 SEC2 = NSECF(NHMS2)
484
485 C***********************************************************************
486 C* COMPUTE DAYS IN 4-YEAR CYCLE *
487 C***********************************************************************
488
489 IF(FIRST) THEN
490 DO I=15,48
491 MNDY(I) = MNDY(I-12) + 365
492 ENDDO
493 FIRST=.FALSE.
494 ENDIF
495
496 C***********************************************************************
497 C* COMPUTE INTERPOLATION FACTORS *
498 C***********************************************************************
499
500 time00 = DAY + MNDY(MONTH +12*MOD(YEAR ,4)) + float(sec )/86400.
501 time1 = DAY1 + MNDY(MONTH1+12*MOD(YEAR1,4)) + float(sec1)/86400.
502 time2 = DAY2 + MNDY(MONTH2+12*MOD(YEAR2,4)) + float(sec2)/86400.
503
504 if( time00 .lt.time1 ) time00 = time00 + dayscy
505 if( time2.lt.time1 ) time2 = time2 + dayscy
506
507 fac1 = (time2-time00)/(time2-time1)
508 fac2 = (time00-time1)/(time2-time1)
509
510 RETURN
511 END
512
513 subroutine tick (nymd,nhms,ndt)
514 C***********************************************************************
515 C Purpose
516 C Tick the Date (nymd) and Time (nhms) by NDT (seconds)
517 C
518 C***********************************************************************
519 implicit none
520
521 integer nymd,nhms,ndt
522
523 integer nsec,nsecf,incymd,nhmsf
524
525 IF(NDT.NE.0) THEN
526 NSEC = NSECF(NHMS) + NDT
527
528 IF (NSEC.GT.86400) THEN
529 DO WHILE (NSEC.GT.86400)
530 NSEC = NSEC - 86400
531 NYMD = INCYMD (NYMD,1)
532 ENDDO
533 ENDIF
534
535 IF (NSEC.EQ.86400) THEN
536 NSEC = 0
537 NYMD = INCYMD (NYMD,1)
538 ENDIF
539
540 IF (NSEC.LT.00000) THEN
541 DO WHILE (NSEC.LT.0)
542 NSEC = 86400 + NSEC
543 NYMD = INCYMD (NYMD,-1)
544 ENDDO
545 ENDIF
546
547 NHMS = NHMSF (NSEC)
548 ENDIF
549
550 #ifdef FIZHI_USE_FIXED_DAY
551 NYMD = 20040321
552 #endif
553
554 RETURN
555 END
556
557 subroutine tic_time (mymd,mhms,ndt)
558 C***********************************************************************
559 C PURPOSE
560 C Tick the Clock by NDT (seconds)
561 C
562 C***********************************************************************
563 implicit none
564 #include "chronos.h"
565
566 integer mymd,mhms,ndt
567
568 integer nsec,nsecf,incymd,nhmsf
569
570 IF(NDT.NE.0) THEN
571 NSEC = NSECF(NHMS) + NDT
572
573 IF (NSEC.GT.86400) THEN
574 DO WHILE (NSEC.GT.86400)
575 NSEC = NSEC - 86400
576 NYMD = INCYMD (NYMD,1)
577 ENDDO
578 ENDIF
579
580 IF (NSEC.EQ.86400) THEN
581 NSEC = 0
582 NYMD = INCYMD (NYMD,1)
583 ENDIF
584
585 IF (NSEC.LT.00000) THEN
586 DO WHILE (NSEC.LT.0)
587 NSEC = 86400 + NSEC
588 NYMD = INCYMD (NYMD,-1)
589 ENDDO
590 ENDIF
591
592 NHMS = NHMSF (NSEC)
593 ENDIF
594
595 C Pass Back Current Updated Time
596 C ------------------------------
597 mymd = nymd
598 mhms = nhms
599
600 RETURN
601 END
602
603 FUNCTION NALARM (MHMS,NYMD,NHMS,NYMD0,NHMS0)
604 C***********************************************************************
605 C PURPOSE
606 C COMPUTES MODULO-FRACTION BETWEEN MHHS AND TOTAL TIME
607 C USAGE
608 C ARGUMENTS DESCRIPTION
609 C MHMS INTERVAL FREQUENCY (HHMMSS)
610 C NYMD CURRENT YYMMDD
611 C NHMS CURRENT HHMMSS
612 C NYMD0 BEGINNING YYMMDD
613 C NHMS0 BEGINNING HHMMSS
614 C
615 C***********************************************************************
616 implicit none
617
618 integer nalarm,MHMS,NYMD,NHMS,NYMD0,NHMS0
619
620 integer nsday, ncycle
621 PARAMETER ( NSDAY = 86400 )
622 PARAMETER ( NCYCLE = 1461*24*3600 )
623
624 INTEGER YEAR, MONTH, DAY, SEC, YEAR0, MONTH0, DAY0, SEC0
625
626 integer MNDY(12*4)
627 DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,
628 & 397,34*0 /
629
630 integer i,nsecf,iday,iday0,nsec,nsec0,ntime
631
632 C***********************************************************************
633 C* COMPUTE # OF DAYS IN A 4-YEAR CYCLE *
634 C***********************************************************************
635
636 DO I=15,48
637 MNDY(I) = MNDY(I-12) + 365
638 ENDDO
639
640 C***********************************************************************
641 C* SET CURRENT AND BEGINNING TIMES *
642 C***********************************************************************
643
644 YEAR = NYMD / 10000
645 MONTH = MOD(NYMD,10000) / 100
646 DAY = MOD(NYMD,100)
647 SEC = NSECF(NHMS)
648
649 YEAR0 = NYMD0 / 10000
650 MONTH0 = MOD(NYMD0,10000) / 100
651 DAY0 = MOD(NYMD0,100)
652 SEC0 = NSECF(NHMS0)
653
654 C***********************************************************************
655 C* COMPUTE POSITIONS IN CYCLE FOR CURRENT AND BEGINNING TIMES *
656 C***********************************************************************
657
658 IDAY = (DAY -1) + MNDY( MONTH +12*MOD(YEAR ,4) )
659 IDAY0 = (DAY0-1) + MNDY( MONTH0+12*MOD(YEAR0,4) )
660
661 NSEC = IDAY *NSDAY + SEC
662 NSEC0 = IDAY0*NSDAY + SEC0
663
664 NTIME = NSEC-NSEC0
665 IF (NTIME.LT.0 ) NTIME = NTIME + NCYCLE
666 NALARM = NTIME
667 IF ( MHMS.NE.0 ) NALARM = MOD( NALARM,NSECF(MHMS) )
668
669 RETURN
670 END
671
672 FUNCTION NALARM2(MHMS,NYMD,NHMS,NYMD0,NHMS0)
673 C***********************************************************************
674 C PURPOSE
675 C COMPUTES MODULO-FRACTION BETWEEN MHHS AND TOTAL TIME
676 C USAGE
677 C ARGUMENTS DESCRIPTION
678 C MHMS INTERVAL FREQUENCY (MMDDHHMMSS)
679 C NYMD CURRENT YYMMDD
680 C NHMS CURRENT HHMMSS
681 C NYMD0 BEGINNING YYMMDD
682 C NHMS0 BEGINNING HHMMSS
683 C
684 C***********************************************************************
685 implicit none
686
687 integer nalarm2,MHMS,NYMD,NHMS,NYMD0,NHMS0
688
689 integer nsday, ncycle
690 PARAMETER ( NSDAY = 86400 )
691 PARAMETER ( NCYCLE = 1461*24*3600 )
692
693 INTEGER YEAR, MONTH, DAY, SEC, YEAR0, MONTH0, DAY0, SEC0
694
695 integer MNDY(12*4)
696 DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,
697 & 397,34*0 /
698 INTEGER NDPM(12)
699 DATA NDPM /31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/
700
701 integer i,nsecf,iday,iday0,nsec,nsec0,ntime
702 integer NHMMSS,NMMDD
703 integer iloop
704 integer testnymd,testnhms,testndpm
705
706 C***********************************************************************
707 C* COMPUTE # OF DAYS IN A 4-YEAR CYCLE *
708 C***********************************************************************
709
710 DO I=15,48
711 MNDY(I) = MNDY(I-12) + 365
712 ENDDO
713
714 C***********************************************************************
715 C* SET CURRENT AND BEGINNING TIMES *
716 C***********************************************************************
717
718 YEAR = NYMD / 10000
719 MONTH = MOD(NYMD,10000) / 100
720 DAY = MOD(NYMD,100)
721 SEC = NSECF(NHMS)
722
723 YEAR0 = NYMD0 / 10000
724 MONTH0 = MOD(NYMD0,10000) / 100
725 DAY0 = MOD(NYMD0,100)
726 SEC0 = NSECF(NHMS0)
727
728 C***********************************************************************
729 C* COMPUTE POSITIONS IN CYCLE FOR CURRENT AND BEGINNING TIMES *
730 C***********************************************************************
731
732 IDAY = (DAY -1) + MNDY( MONTH +12*MOD(YEAR ,4) )
733 IDAY0 = (DAY0-1) + MNDY( MONTH0+12*MOD(YEAR0,4) )
734
735 NSEC = IDAY *NSDAY + SEC
736 NSEC0 = IDAY0*NSDAY + SEC0
737
738 NTIME = NSEC-NSEC0
739 IF(NTIME.LT.0) NTIME = NTIME + NCYCLE
740 NALARM2 = NTIME
741 IF(MHMS.NE.0)NALARM2 = MOD( NALARM2,NSECF(MHMS) )
742 IF(MHMS.GE.1000000) THEN
743 testnymd=nymd0
744 testnhms=nhms0
745 NMMDD = MHMS / 1000000
746 NHMMSS = MOD(MHMS,1000000)
747 do iloop=1,100000
748 testnymd=testnymd + nmmdd
749 testnhms=testnhms + nhmmss
750 year0=testnymd/10000
751 month0=mod(testnymd,10000)/100
752 day0 = mod(testnymd,100)
753 testndpm = ndpm(month0)
754 if( month0.eq.2 .and. mod(year0,4).eq.0) testndpm = 29
755 if(testnhms.ge.240000) then
756 testnhms = testnhms-240000
757 testnymd = testnymd + 1
758 day0 = day0 + 1
759 endif
760 if(day0.gt.testndpm) then
761 testnymd = testnymd - testndpm
762 testnymd = testnymd + 100
763 day0 = day0 - testndpm
764 month0 = month0 + 1
765 endif
766 if(month0.gt.12) then
767 month0 = month0 - 12
768 year0 = year0 + 1
769 testnymd = testnymd + 10000 - 1200
770 endif
771 sec0 = nsecf(testnhms)
772 iday0 = (day0-1) + MNDY(month0+12*mod(year0,4) )
773 nsec0 = iday0 *nsday + sec0
774 if( (testnymd.gt.nymd) .or.
775 & (testnymd.eq.testnymd) .and. (testnhms.gt.nhms) )
776 & go to 200
777 nalarm2 = nsec-nsec0
778 enddo
779 200 continue
780 ENDIF
781
782 RETURN
783 END
784
785 FUNCTION INCYMD (NYMD,M)
786 C***********************************************************************
787 C PURPOSE
788 C INCYMD: NYMD CHANGED BY ONE DAY
789 C MODYMD: NYMD CONVERTED TO JULIAN DATE
790 C DESCRIPTION OF INPUT VARIABLES
791 C NYMD CURRENT DATE IN YYMMDD FORMAT
792 C M +/- 1 (DAY ADJUSTMENT)
793 C
794 C***********************************************************************
795 implicit none
796 integer incymd,nymd,m
797
798 integer ny,nm,nd,ny00,modymd
799
800 INTEGER NDPM(12)
801 DATA NDPM /31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/
802 LOGICAL LEAP
803 DATA NY00 /1900 /
804 LEAP(NY) = MOD(NY,4).EQ.0 .AND. (NY.NE.0 .OR. MOD(NY00,400).EQ.0)
805
806 C***********************************************************************
807 C
808 NY = NYMD / 10000
809 NM = MOD(NYMD,10000) / 100
810 ND = MOD(NYMD,100) + M
811
812 IF (ND.EQ.0) THEN
813 NM = NM - 1
814 IF (NM.EQ.0) THEN
815 NM = 12
816 NY = NY - 1
817 ENDIF
818 ND = NDPM(NM)
819 IF (NM.EQ.2 .AND. LEAP(NY)) ND = 29
820 ENDIF
821
822 IF (ND.EQ.29 .AND. NM.EQ.2 .AND. LEAP(NY)) GO TO 20
823
824 IF (ND.GT.NDPM(NM)) THEN
825 ND = 1
826 NM = NM + 1
827 IF (NM.GT.12) THEN
828 NM = 1
829 NY = NY + 1
830 ENDIF
831 ENDIF
832
833 20 CONTINUE
834 INCYMD = NY*10000 + NM*100 + ND
835
836 RETURN
837
838 C***********************************************************************
839 C E N T R Y M O D Y M D
840 C***********************************************************************
841
842 ENTRY MODYMD (NYMD)
843
844 NY = NYMD / 10000
845 NM = MOD(NYMD,10000) / 100
846 ND = MOD(NYMD,100)
847
848 40 CONTINUE
849 IF (NM.LE.1) GO TO 60
850 NM = NM - 1
851 ND = ND + NDPM(NM)
852 IF (NM.EQ.2 .AND. LEAP(NY)) ND = ND + 1
853 GO TO 40
854
855 60 CONTINUE
856 MODYMD = ND
857
858 RETURN
859 END
860
861 SUBROUTINE ASTRO ( NYMD,NHMS,ALAT,ALON,IRUN,COSZ,RA )
862 C***********************************************************************
863 C
864 C INPUT:
865 C ======
866 C NYMD : CURRENT YYMMDD
867 C NHMS : CURRENT HHMMSS
868 C ALAT(IRUN):LATITUDES IN DEGREES.
869 C ALON(IRUN):LONGITUDES IN DEGREES. (0 = GREENWICH, + = EAST).
870 C IRUN : # OF POINTS TO CALCULATE
871 C
872 C OUTPUT:
873 C =======
874 C COSZ(IRUN) : COSINE OF ZENITH ANGLE.
875 C RA : EARTH-SUN DISTANCE IN UNITS OF
876 C THE ORBITS SEMI-MAJOR AXIS.
877 C
878 C NOTE:
879 C =====
880 C THE INSOLATION AT THE TOP OF THE ATMOSPHERE IS:
881 C
882 C S(I) = (SOLAR CONSTANT)*(1/RA**2)*COSZ(I),
883 C
884 C WHERE:
885 C RA AND COSZ(I) ARE THE TWO OUTPUTS OF THIS SUBROUTINE.
886 C
887 C***********************************************************************
888
889 implicit none
890
891 C Input Variables
892 C ---------------
893 integer nymd, nhms, irun
894 _RL getcon, cosz(irun), alat(irun), alon(irun), ra
895
896 C Local Variables
897 C ---------------
898 integer year, day, sec, month, iday, idayp1
899 integer dayscy
900 integer i,nsecf,k,km,kp
901
902 _RL hc
903 _RL pi, zero, one, two, six, dg2rd, yrlen, eqnx, ob, ecc, per
904 _RL daylen, fac, thm, thp, thnow, zs, zc, sj, cj
905
906 parameter ( zero = 0.0 )
907 parameter ( one = 1.0 )
908 parameter ( two = 2.0 )
909 parameter ( six = 6.0 )
910 parameter ( dayscy = 365*4 + 1 )
911
912 _RL TH(DAYSCY),T0,T1,T2,T3,T4,FUN,Y
913 INTEGER MNDY(12*4)
914
915 LOGICAL FIRST
916 DATA FIRST/.TRUE./
917 SAVE
918
919 DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,
920 & 397,34*0 /
921
922 FUN(Y,PI,ECC,YRLEN,PER) = (TWO*PI/((ONE-ECC**2)**1.5))*(ONE/YRLEN)
923 & * (ONE - ECC*COS(Y-PER)) ** 2
924
925 C***********************************************************************
926 C* SET SOME CONSTANTS *
927 C***********************************************************************
928 pi = getcon('PI')
929 dg2rd = getcon('DEG2RAD')
930 yrlen = getcon('YRLEN')
931 ob = getcon('OBLDEG') * dg2rd
932 daylen = getcon('SDAY')
933 eqnx = getcon('VERNAL EQUINOX')
934 ecc = getcon('ECCENTRICITY')
935 per = getcon('PERIHELION') * dg2rd
936
937 C***********************************************************************
938 C* SET CURRENT TIME *
939 C***********************************************************************
940
941 YEAR = NYMD / 10000
942 MONTH = MOD(NYMD,10000) / 100
943 DAY = MOD(NYMD,100)
944 SEC = NSECF(NHMS)
945
946 C***********************************************************************
947 C* COMPUTE DAY-ANGLES FOR 4-YEAR CYCLE *
948 C***********************************************************************
949
950 IF(FIRST) THEN
951 DO 100 I=15,48
952 MNDY(I) = MNDY(I-12) + 365
953 100 CONTINUE
954
955 KM = INT(EQNX) + 1
956 FAC = KM-EQNX
957 T0 = ZERO
958 T1 = FUN(T0,PI,ECC,YRLEN,PER )*FAC
959 T2 = FUN(ZERO+T1/TWO,PI,ECC,YRLEN,PER)*FAC
960 T3 = FUN(ZERO+T2/TWO,PI,ECC,YRLEN,PER)*FAC
961 T4 = FUN(ZERO+T3,PI,ECC,YRLEN,PER )*FAC
962 TH(KM) = (T1 + TWO*(T2 + T3) + T4) / SIX
963
964 DO 200 K=2,DAYSCY
965 T1 = FUN(TH(KM),PI,ECC,YRLEN,PER )
966 T2 = FUN(TH(KM)+T1/TWO,PI,ECC,YRLEN,PER)
967 T3 = FUN(TH(KM)+T2/TWO,PI,ECC,YRLEN,PER)
968 T4 = FUN(TH(KM)+T3,PI,ECC,YRLEN,PER )
969 KP = MOD(KM,DAYSCY) + 1
970 TH(KP) = TH(KM) + (T1 + TWO*(T2 + T3) + T4) / SIX
971 KM = KP
972 200 CONTINUE
973
974 FIRST=.FALSE.
975 ENDIF
976
977 C***********************************************************************
978 C* COMPUTE EARTH-SUN DISTANCE TO CURRENT SECOND *
979 C***********************************************************************
980
981 IDAY = DAY + MNDY(MONTH+12*MOD(YEAR,4) )
982 IDAYP1 = MOD( IDAY,DAYSCY) + 1
983 THM = MOD( TH(IDAY) ,TWO*PI)
984 THP = MOD( TH(IDAYP1),TWO*PI)
985
986 IF(THP.LT.THM) THP = THP + TWO*PI
987 FAC = FLOAT(SEC)/DAYLEN
988 THNOW = THM*(ONE-FAC) + THP*FAC
989
990 ZS = SIN(THNOW) * SIN(OB)
991 ZC = SQRT(ONE-ZS*ZS)
992 RA = (1.-ECC*ECC) / ( ONE-ECC*COS(THNOW-PER) )
993
994 C***********************************************************************
995 C* COMPUTE COSINE OF THE ZENITH ANGLE *
996 C***********************************************************************
997
998 FAC = FAC*TWO*PI + PI
999 DO I = 1,IRUN
1000
1001 HC = COS( FAC+ALON(I)*DG2RD )
1002 SJ = SIN(ALAT(I)*DG2RD)
1003 CJ = SQRT(ONE-SJ*SJ)
1004
1005 COSZ(I) = SJ*ZS + CJ*ZC*HC
1006 IF( COSZ(I).LT.ZERO ) COSZ(I) = ZERO
1007 ENDDO
1008
1009 RETURN
1010 END
1011
1012 subroutine time_bound(nymd,nhms,nymd1,nhms1,nymd2,nhms2,imnm,imnp)
1013 C***********************************************************************
1014 C PURPOSE
1015 C Compute Date and Time boundaries.
1016 C
1017 C ARGUMENTS DESCRIPTION
1018 C nymd .... Current Date
1019 C nhms .... Current Time
1020 C nymd1 ... Previous Date Boundary
1021 C nhms1 ... Previous Time Boundary
1022 C nymd2 ... Subsequent Date Boundary
1023 C nhms2 ... Subsequent Time Boundary
1024 C
1025 C imnm .... Previous Time Index for Interpolation
1026 C imnp .... Subsequent Time Index for Interpolation
1027 C
1028 C***********************************************************************
1029
1030 implicit none
1031 integer nymd,nhms, nymd1,nhms1, nymd2,nhms2
1032
1033 C Local Variables
1034 C ---------------
1035 integer month,day,nyear,midmon1,midmon,midmon2
1036 integer imnm,imnp
1037 INTEGER DAYS(14), daysm, days0, daysp
1038 DATA DAYS /31,31,28,31,30,31,30,31,31,30,31,30,31,31/
1039
1040 integer nmonf,ndayf,n
1041 NMONF(N) = MOD(N,10000)/100
1042 NDAYF(N) = MOD(N,100)
1043
1044 C*********************************************************************
1045 C**** Find Proper Month and Time Boundaries for Climatological Data **
1046 C*********************************************************************
1047
1048 MONTH = NMONF(NYMD)
1049 DAY = NDAYF(NYMD)
1050
1051 daysm = days(month )
1052 days0 = days(month+1)
1053 daysp = days(month+2)
1054
1055 C Check for Leap Year
1056 C -------------------
1057 nyear = nymd/10000
1058 if( 4*(nyear/4).eq.nyear ) then
1059 if( month.eq.3 ) daysm = daysm+1
1060 if( month.eq.2 ) days0 = days0+1
1061 if( month.eq.1 ) daysp = daysp+1
1062 endif
1063
1064 MIDMON1 = daysm/2 + 1
1065 MIDMON = days0/2 + 1
1066 MIDMON2 = daysp/2 + 1
1067
1068
1069 IF(DAY.LT.MIDMON) THEN
1070 imnm = month
1071 imnp = month + 1
1072 nymd2 = (nymd/10000)*10000 + month*100 + midmon
1073 nhms2 = 000000
1074 nymd1 = nymd2
1075 nhms1 = nhms2
1076 call tick ( nymd1,nhms1, -midmon *86400 )
1077 call tick ( nymd1,nhms1,-(daysm-midmon1)*86400 )
1078 ELSE
1079 IMNM = MONTH + 1
1080 IMNP = MONTH + 2
1081 nymd1 = (nymd/10000)*10000 + month*100 + midmon
1082 nhms1 = 000000
1083 nymd2 = nymd1
1084 nhms2 = nhms1
1085 call tick ( nymd2,nhms2,(days0-midmon)*86400 )
1086 call tick ( nymd2,nhms2, midmon2*86400 )
1087 ENDIF
1088
1089 C -------------------------------------------------------------
1090 C Note: At this point, imnm & imnp range between 01-14, where
1091 C 01 -> Previous years December
1092 C 02-13 -> Current years January-December
1093 C 14 -> Next years January
1094 C -------------------------------------------------------------
1095
1096 imnm = imnm-1
1097 imnp = imnp-1
1098
1099 if( imnm.eq.0 ) imnm = 12
1100 if( imnp.eq.0 ) imnp = 12
1101 if( imnm.eq.13 ) imnm = 1
1102 if( imnp.eq.13 ) imnp = 1
1103
1104 return
1105 end
1106 subroutine time2freq2(MMDD,NYMD,NHMS,timeleft)
1107 C***********************************************************************
1108 C PURPOSE
1109 C COMPUTES TIME IN SECONDS UNTIL WE REACH THE NEXT MMDD
1110 C (ASSUME that the target time is 0Z)
1111 C
1112 C ARGUMENTS DESCRIPTION
1113 C MMDD FREQUENCY (MMDDHHMMSS)
1114 C NYMD CURRENT YYMMDD
1115 C NHMS CURRENT HHMMSS
1116 C TIMELEFT TIME LEFT (SECONDS)
1117 C
1118 C NOTES - Only used when the frequency is in units of months
1119 C Assumes that we always want to be at a month boundary
1120 C***********************************************************************
1121 implicit none
1122
1123 integer mmdd,nymd,nhms,timeleft,daysleft
1124
1125 integer nsday
1126 PARAMETER ( NSDAY = 86400 )
1127 integer year, month, day, sec
1128 integer yearnext, monthnext, daynext
1129 integer i,nsecf,iday,idaynext,nsec
1130 integer testnymd
1131 integer MNDY(12*4)
1132 DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,
1133 & 397,34*0 /
1134
1135 C***********************************************************************
1136 C* COMPUTE # OF DAYS IN A 4-YEAR CYCLE *
1137 C***********************************************************************
1138 DO I=15,48
1139 MNDY(I) = MNDY(I-12) + 365
1140 ENDDO
1141 C***********************************************************************
1142 C* SET CURRENT TIME ELEMENTS *
1143 C***********************************************************************
1144 YEAR = NYMD / 10000
1145 MONTH = MOD(NYMD,10000) / 100
1146 DAY = MOD(NYMD,100)
1147 SEC = NSECF(NHMS)
1148 C***********************************************************************
1149 C* COMPUTE POSITIONS IN CYCLE FOR CURRENT AND BEGINNING TIMES *
1150 C***********************************************************************
1151 IDAY = (DAY -1) + MNDY( MONTH +12*MOD(YEAR ,4) )
1152 NSEC = IDAY *NSDAY + SEC
1153
1154 testnymd=nymd + mmdd
1155 yearnext=testnymd/10000
1156 monthnext=mod(testnymd,10000)/100
1157 daynext = 1
1158 if(monthnext.gt.12) then
1159 monthnext = monthnext - 12
1160 yearnext = yearnext + 1
1161 endif
1162 testnymd = yearnext*10000 + monthnext*100 + daynext
1163 idaynext = MNDY(monthnext+12*mod(yearnext,4) )
1164 daysleft = idaynext - iday
1165 if(daysleft.lt.0) daysleft = daysleft + 1461
1166
1167 timeleft = daysleft * nsday - sec
1168
1169 RETURN
1170 END

  ViewVC Help
Powered by ViewVC 1.1.22