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