1 |
edhill |
1.2 |
C $Header: /u/u3/gcmpack/MITgcm/pkg/cal/cal_getmonthsrec.F,v 1.1.20.2 2003/10/07 20:46:37 adcroft Exp $ |
2 |
|
|
C $Name: $ |
3 |
heimbach |
1.1 |
|
4 |
edhill |
1.2 |
#include "CAL_OPTIONS.h" |
5 |
heimbach |
1.1 |
|
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 middate0(4) |
55 |
|
|
integer middate1(4) |
56 |
|
|
integer prevdate(4) |
57 |
|
|
integer shifttime(4) |
58 |
|
|
integer startofmonth(4) |
59 |
|
|
integer endofmonth(4) |
60 |
|
|
integer difftime(4) |
61 |
|
|
integer present |
62 |
|
|
integer previous |
63 |
|
|
integer next |
64 |
|
|
integer prevcount |
65 |
|
|
integer modelsteptime(4) |
66 |
|
|
|
67 |
|
|
_RL currentsecs |
68 |
|
|
_RL prevsecs |
69 |
|
|
_RL midsecs_np |
70 |
|
|
_RL diffsecs |
71 |
|
|
_RL midsecs |
72 |
|
|
|
73 |
|
|
c == end of interface == |
74 |
|
|
|
75 |
|
|
ce --> Include a check whether the right calendar is used. |
76 |
|
|
|
77 |
|
|
shifttime(1) = 1 |
78 |
|
|
shifttime(2) = 0 |
79 |
|
|
shifttime(3) = 0 |
80 |
|
|
shifttime(4) = -1 |
81 |
|
|
|
82 |
|
|
call cal_TimeInterval( -modelstep, 'secs', modelsteptime, |
83 |
|
|
& mythid ) |
84 |
|
|
|
85 |
|
|
c Determine the current date and the current month. |
86 |
|
|
call cal_GetDate( myiter, mytime, currentdate, mythid ) |
87 |
|
|
|
88 |
|
|
present = mod(currentdate(1)/100,100) |
89 |
|
|
startofmonth(1) = (currentdate(1)/100)*100 + 1 |
90 |
|
|
startofmonth(2) = 0 |
91 |
|
|
startofmonth(3) = 0 |
92 |
|
|
startofmonth(4) = 0 |
93 |
|
|
endofmonth(1) = (currentdate(1)/100)*100 + |
94 |
|
|
& ndaymonth(present,currentdate(3)) |
95 |
|
|
endofmonth(2) = 235959 |
96 |
|
|
endofmonth(3) = 0 |
97 |
|
|
endofmonth(4) = 0 |
98 |
|
|
|
99 |
|
|
call cal_FullDate( startofmonth(1), startofmonth(2), |
100 |
|
|
& startofmonth, mythid ) |
101 |
|
|
call cal_FullDate( endofmonth(1), endofmonth(2), |
102 |
|
|
& endofmonth, mythid ) |
103 |
|
|
|
104 |
|
|
c Determine middle of current month. |
105 |
|
|
currentsecs = float( |
106 |
|
|
& (mod(currentdate(1),100)-1)*secondsperday + |
107 |
|
|
& currentdate(2)/10000*secondsperhour + |
108 |
|
|
& mod(currentdate(2)/100,100)*secondsperminute + |
109 |
|
|
& mod(currentdate(2),100) |
110 |
|
|
& ) |
111 |
|
|
midsecs = float(ndaymonth(present,currentdate(3))* |
112 |
|
|
& secondsperday/2) |
113 |
|
|
|
114 |
|
|
call cal_TimeInterval( midsecs, 'secs', midtime, mythid ) |
115 |
|
|
call cal_AddTime( startofmonth, midtime, middate, mythid ) |
116 |
|
|
call cal_AddTime( currentdate, modelsteptime, prevdate, mythid ) |
117 |
|
|
|
118 |
|
|
prevsecs = float( |
119 |
|
|
& (mod(prevdate(1),100)-1)*secondsperday + |
120 |
|
|
& prevdate(2)/10000*secondsperhour + |
121 |
|
|
& mod(prevdate(2)/100,100)*secondsperminute + |
122 |
|
|
& mod(prevdate(2),100) |
123 |
|
|
& ) |
124 |
|
|
|
125 |
|
|
c-- Set switches for reading new records. |
126 |
|
|
first = ((mytime - modelstart) .lt. 0.5*modelstep) |
127 |
|
|
|
128 |
|
|
if ( first ) then |
129 |
|
|
changed = .false. |
130 |
|
|
endif |
131 |
|
|
|
132 |
|
|
if ( currentsecs .lt. midsecs ) then |
133 |
|
|
|
134 |
|
|
count0 = mod(present+nmonthyear-2,nmonthyear)+1 |
135 |
|
|
prevcount = count0 |
136 |
|
|
|
137 |
|
|
shifttime(1) = -shifttime(1) |
138 |
|
|
call cal_AddTime( startofmonth, shifttime, middate0, mythid ) |
139 |
|
|
middate0(1) = (middate0(1)/100)*100 + 1 |
140 |
|
|
middate0(2) = 0 |
141 |
|
|
middate0(3) = 0 |
142 |
|
|
middate0(4) = 0 |
143 |
|
|
call cal_FullDate( middate0(1), middate0(2), middate0, |
144 |
|
|
& mythid ) |
145 |
|
|
|
146 |
|
|
previous = mod(middate0(1)/100,100) |
147 |
|
|
|
148 |
|
|
midsecs_np = float(ndaymonth(previous,middate0(3))* |
149 |
|
|
& secondsperday/2) |
150 |
|
|
|
151 |
|
|
call cal_TimeInterval( midsecs_np, 'secs', midtime, mythid ) |
152 |
|
|
call cal_AddTime( middate0, midtime, middate0, mythid ) |
153 |
|
|
|
154 |
|
|
count1 = present |
155 |
|
|
|
156 |
|
|
middate1(1) = middate(1) |
157 |
|
|
middate1(2) = middate(2) |
158 |
|
|
middate1(3) = middate(3) |
159 |
|
|
middate1(4) = middate(4) |
160 |
|
|
|
161 |
|
|
else |
162 |
|
|
|
163 |
|
|
count0 = present |
164 |
|
|
|
165 |
|
|
if ( prevsecs .lt. midsecs ) then |
166 |
|
|
prevcount = mod(present+nmonthyear-2,nmonthyear)+1 |
167 |
|
|
else |
168 |
|
|
prevcount = present |
169 |
|
|
endif |
170 |
|
|
|
171 |
|
|
middate0(1) = middate(1) |
172 |
|
|
middate0(2) = middate(2) |
173 |
|
|
middate0(3) = middate(3) |
174 |
|
|
middate0(4) = middate(4) |
175 |
|
|
|
176 |
|
|
count1 = mod(present+1,nmonthyear) |
177 |
|
|
if ( count1 .EQ. 0 ) count1 = nmonthyear |
178 |
|
|
|
179 |
|
|
call cal_AddTime( endofmonth, shifttime, middate1, mythid ) |
180 |
|
|
middate1(1) = (middate1(1)/100)*100 + 1 |
181 |
|
|
middate1(2) = 0 |
182 |
|
|
middate1(3) = 0 |
183 |
|
|
middate1(4) = 0 |
184 |
|
|
|
185 |
|
|
call cal_FullDate( middate1(1), middate1(2), middate1, |
186 |
|
|
& mythid ) |
187 |
|
|
next = mod(middate1(1)/100,100) |
188 |
|
|
midsecs_np = float(ndaymonth(next,middate1(3))* |
189 |
|
|
& secondsperday/2) |
190 |
|
|
call cal_TimeInterval( midsecs_np, 'secs', midtime, mythid ) |
191 |
|
|
call cal_AddTime( middate1, midtime, middate1, mythid ) |
192 |
|
|
|
193 |
|
|
endif |
194 |
|
|
|
195 |
|
|
call cal_SubDates( middate1, middate0, difftime, mythid ) |
196 |
|
|
call cal_ToSeconds( difftime, diffsecs, mythid ) |
197 |
|
|
|
198 |
|
|
c Set counters, switches, and the linear interpolation factor. |
199 |
|
|
if ( (.not. first) .and. (prevcount .ne. count0) ) then |
200 |
|
|
changed = .true. |
201 |
|
|
else |
202 |
|
|
changed = .false. |
203 |
|
|
endif |
204 |
|
|
|
205 |
|
|
if ( currentsecs .lt. midsecs ) then |
206 |
|
|
fac = (midsecs - currentsecs)/diffsecs |
207 |
|
|
else |
208 |
|
|
fac = (2.*midsecs + midsecs_np - currentsecs)/ |
209 |
|
|
& diffsecs |
210 |
|
|
endif |
211 |
|
|
|
212 |
|
|
return |
213 |
|
|
end |
214 |
|
|
|