1 |
C $Header: /u/gcmpack/MITgcm/pkg/cal/cal_getmonthsrec.F,v 1.2 2003/10/09 04:19:19 edhill Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "CAL_OPTIONS.h" |
5 |
|
6 |
subroutine cal_GetMonthsRec( |
7 |
O fac, first, changed, |
8 |
O count0, count1, |
9 |
I mytime, myiter, mythid |
10 |
& ) |
11 |
|
12 |
c ================================================================== |
13 |
c SUBROUTINE cal_GetMonthsRec |
14 |
c ================================================================== |
15 |
c |
16 |
c o Given the current model time or iteration number this routine |
17 |
c returns the corrresponding months that will have to be used in |
18 |
c order to interpolate monthly mean fields. The routine derives |
19 |
c from *exf_GetMonthsRec* of the external forcing package. |
20 |
c |
21 |
c started: Christian Eckert eckert@mit.edu 21-Apr-2000 |
22 |
c - ported from the external forcing package and slightly |
23 |
c modified (10 --> nmonthyear-2, 12 --> nmonthyear). |
24 |
c |
25 |
c changed: Patrick Heimbach heimbach@mit.edu 15-Jun-2000 |
26 |
c - fixed bug for count1 = nmonthyear |
27 |
c |
28 |
c ================================================================== |
29 |
c SUBROUTINE cal_GetMonthsRec |
30 |
c ================================================================== |
31 |
|
32 |
implicit none |
33 |
|
34 |
c == global variables == |
35 |
|
36 |
#include "cal.h" |
37 |
|
38 |
c == routine arguments == |
39 |
|
40 |
_RL fac |
41 |
logical first |
42 |
logical changed |
43 |
integer count0 |
44 |
integer count1 |
45 |
_RL mytime |
46 |
integer myiter |
47 |
integer mythid |
48 |
|
49 |
c == local variables == |
50 |
|
51 |
integer currentdate(4) |
52 |
integer midtime(4) |
53 |
integer middate(4) |
54 |
integer tempDate(4) |
55 |
integer middate0_1, middate0_2 |
56 |
integer middate0(4) |
57 |
integer middate1_1, middate1_2 |
58 |
integer middate1(4) |
59 |
integer prevdate(4) |
60 |
integer shifttime(4) |
61 |
integer startofmonth_1, startofmonth_2 |
62 |
integer endofmonth_1, endofmonth_2 |
63 |
integer startofmonth(4) |
64 |
integer endofmonth(4) |
65 |
integer difftime(4) |
66 |
integer present |
67 |
integer previous |
68 |
integer next |
69 |
integer prevcount |
70 |
integer modelsteptime(4) |
71 |
|
72 |
_RL currentsecs |
73 |
_RL prevsecs |
74 |
_RL midsecs_np |
75 |
_RL diffsecs |
76 |
_RL midsecs |
77 |
|
78 |
c == end of interface == |
79 |
|
80 |
ce --> Include a check whether the right calendar is used. |
81 |
|
82 |
shifttime(1) = 1 |
83 |
shifttime(2) = 0 |
84 |
shifttime(3) = 0 |
85 |
shifttime(4) = -1 |
86 |
|
87 |
call cal_TimeInterval( -modelstep, 'secs', modelsteptime, |
88 |
& mythid ) |
89 |
|
90 |
c Determine the current date and the current month. |
91 |
call cal_GetDate( myiter, mytime, currentdate, mythid ) |
92 |
|
93 |
present = mod(currentdate(1)/100,100) |
94 |
startofmonth_1 = (currentdate(1)/100)*100 + 1 |
95 |
startofmonth_2 = 0 |
96 |
call cal_FullDate( startofmonth_1, startofmonth_2, |
97 |
& startofmonth, mythid ) |
98 |
|
99 |
endofmonth_1 = (currentdate(1)/100)*100 + |
100 |
& ndaymonth(present,currentdate(3)) |
101 |
endofmonth_2 = 235959 |
102 |
call cal_FullDate( endofmonth_1, endofmonth_2, |
103 |
& endofmonth, mythid ) |
104 |
|
105 |
c Determine middle of current month. |
106 |
currentsecs = float( |
107 |
& (mod(currentdate(1),100)-1)*secondsperday + |
108 |
& currentdate(2)/10000*secondsperhour + |
109 |
& mod(currentdate(2)/100,100)*secondsperminute + |
110 |
& mod(currentdate(2),100) |
111 |
& ) |
112 |
midsecs = float(ndaymonth(present,currentdate(3))* |
113 |
& secondsperday/2) |
114 |
|
115 |
call cal_TimeInterval( midsecs, 'secs', midtime, mythid ) |
116 |
call cal_AddTime( startofmonth, midtime, middate, mythid ) |
117 |
call cal_AddTime( currentdate, modelsteptime, prevdate, mythid ) |
118 |
|
119 |
prevsecs = float( |
120 |
& (mod(prevdate(1),100)-1)*secondsperday + |
121 |
& prevdate(2)/10000*secondsperhour + |
122 |
& mod(prevdate(2)/100,100)*secondsperminute + |
123 |
& mod(prevdate(2),100) |
124 |
& ) |
125 |
|
126 |
c-- Set switches for reading new records. |
127 |
first = ((mytime - modelstart) .lt. 0.5*modelstep) |
128 |
|
129 |
if ( first ) then |
130 |
changed = .false. |
131 |
endif |
132 |
|
133 |
if ( currentsecs .lt. midsecs ) then |
134 |
|
135 |
count0 = mod(present+nmonthyear-2,nmonthyear)+1 |
136 |
prevcount = count0 |
137 |
|
138 |
shifttime(1) = -shifttime(1) |
139 |
call cal_AddTime( startofmonth, shifttime, middate0, mythid ) |
140 |
middate0_1 = (middate0(1)/100)*100 + 1 |
141 |
middate0_2 = 0 |
142 |
call cal_FullDate( middate0_1, middate0_2, tempDate, |
143 |
& mythid ) |
144 |
|
145 |
previous = mod(tempDate(1)/100,100) |
146 |
|
147 |
midsecs_np = float(ndaymonth(previous,tempDate(3))* |
148 |
& secondsperday/2) |
149 |
|
150 |
call cal_TimeInterval( midsecs_np, 'secs', midtime, mythid ) |
151 |
call cal_AddTime( tempDate, midtime, middate0, mythid ) |
152 |
|
153 |
count1 = present |
154 |
|
155 |
middate1(1) = middate(1) |
156 |
middate1(2) = middate(2) |
157 |
middate1(3) = middate(3) |
158 |
middate1(4) = middate(4) |
159 |
|
160 |
else |
161 |
|
162 |
count0 = present |
163 |
|
164 |
if ( prevsecs .lt. midsecs ) then |
165 |
prevcount = mod(present+nmonthyear-2,nmonthyear)+1 |
166 |
else |
167 |
prevcount = present |
168 |
endif |
169 |
|
170 |
middate0(1) = middate(1) |
171 |
middate0(2) = middate(2) |
172 |
middate0(3) = middate(3) |
173 |
middate0(4) = middate(4) |
174 |
|
175 |
count1 = mod(present+1,nmonthyear) |
176 |
if ( count1 .EQ. 0 ) count1 = nmonthyear |
177 |
|
178 |
call cal_AddTime( endofmonth, shifttime, middate1, mythid ) |
179 |
middate1_1 = (middate1(1)/100)*100 + 1 |
180 |
middate1_2 = 0 |
181 |
|
182 |
call cal_FullDate( middate1_1, middate1_2, tempDate, |
183 |
& mythid ) |
184 |
next = mod(tempDate(1)/100,100) |
185 |
midsecs_np = float(ndaymonth(next,tempDate(3))* |
186 |
& secondsperday/2) |
187 |
call cal_TimeInterval( midsecs_np, 'secs', midtime, mythid ) |
188 |
call cal_AddTime( tempDate, midtime, middate1, mythid ) |
189 |
|
190 |
endif |
191 |
|
192 |
call cal_SubDates( middate1, middate0, difftime, mythid ) |
193 |
call cal_ToSeconds( difftime, diffsecs, mythid ) |
194 |
|
195 |
c Set counters, switches, and the linear interpolation factor. |
196 |
if ( (.not. first) .and. (prevcount .ne. count0) ) then |
197 |
changed = .true. |
198 |
else |
199 |
changed = .false. |
200 |
endif |
201 |
|
202 |
if ( currentsecs .lt. midsecs ) then |
203 |
fac = (midsecs - currentsecs)/diffsecs |
204 |
else |
205 |
fac = (2.*midsecs + midsecs_np - currentsecs)/ |
206 |
& diffsecs |
207 |
endif |
208 |
|
209 |
return |
210 |
end |
211 |
|