1 |
C $Header: /u/gcmpack/MITgcm/pkg/exf/exf_getffieldrec.F,v 1.25 2014/06/05 15:37:46 jmc Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "EXF_OPTIONS.h" |
5 |
|
6 |
SUBROUTINE EXF_GetFFieldRec( |
7 |
I fldstartdate, fldperiod, |
8 |
I usefldyearlyfields, |
9 |
O fac, |
10 |
O first, changed, |
11 |
O count0, count1, year0, year1, |
12 |
I myTime, myIter, myThid ) |
13 |
|
14 |
c ================================================================== |
15 |
c o Get flags, counters, and the linear interpolation factor for a |
16 |
c given field. |
17 |
c ================================================================== |
18 |
|
19 |
IMPLICIT NONE |
20 |
|
21 |
c == global variables == |
22 |
|
23 |
c cal: modelstart, modelstep |
24 |
#include "EEPARAMS.h" |
25 |
#include "cal.h" |
26 |
#include "EXF_PARAM.h" |
27 |
|
28 |
c == input arguments == |
29 |
c fldstartdate :: time in seconds of first fld record from the |
30 |
c beginning of the model integration or, if |
31 |
c usefldyearlyfields, from the beginning of year |
32 |
c fldperiod :: period between forcing field records |
33 |
c usefldyearlyfields :: when set, use yearly forcing files |
34 |
c myTime :: current time in simulation |
35 |
c myIter :: current iteration number in simulation |
36 |
c myThid :: my thread identification number |
37 |
|
38 |
_RL fldstartdate, fldperiod |
39 |
logical usefldyearlyfields |
40 |
_RL myTime |
41 |
INTEGER myIter, myThid |
42 |
|
43 |
c == output arguments == |
44 |
c fac :: weight of record count0 for linear interpolation purposes |
45 |
c first :: model initialization flag: read two forcing records |
46 |
c changed :: flag indicating that a new forcing record must be read |
47 |
c count0 :: record number for forcing field preceding myTime |
48 |
c count1 :: record number for forcing field following myTime |
49 |
c year0 :: year of forcing file for record preceding myTime |
50 |
c year1 :: year of forcing file for record following myTime |
51 |
|
52 |
_RL fac |
53 |
LOGICAL first, changed |
54 |
INTEGER count0, count1, year0, year1 |
55 |
|
56 |
c == local variables == |
57 |
c mydate :: model date of current time step |
58 |
c yearStartDate :: start of year date for flux record just before mydate |
59 |
c difftime :: time difference between yearStartDate and mydate |
60 |
c fldsectot :: time in seconds from fldstartdate to mydate |
61 |
c fldsecs :: time from start of current forcing period to mydate |
62 |
c fldsecs0 :: time from start of repeat period to mydate |
63 |
c fldsecs1 :: time from end of current forcing period to mydate |
64 |
c secondsInYear :: seconds in the flux year just before mydate |
65 |
c myDateSeconds :: seconds from beginning of year to mydate |
66 |
|
67 |
INTEGER mydate(4) |
68 |
INTEGER yearStartDate(4) |
69 |
INTEGER difftime(4) |
70 |
_RL fldsectot, fldsecs, fldsecs0, fldsecs1 |
71 |
_RL secondsInYear, myDateSeconds |
72 |
|
73 |
CHARACTER*(max_len_mbuf) msgBuf |
74 |
|
75 |
c == external == |
76 |
|
77 |
INTEGER cal_IsLeap |
78 |
EXTERNAL cal_IsLeap |
79 |
|
80 |
c == end of interface == |
81 |
|
82 |
c Set some default values. |
83 |
first = ((myTime - modelstart) .lt. 0.5*modelstep) |
84 |
changed = .FALSE. |
85 |
|
86 |
if ( fldperiod .eq. 0. _d 0 ) then |
87 |
c Read field only once in the beginning. Hack: count1=count0 causes |
88 |
c the model to read the first record twice, but since this this is |
89 |
c done only the first time around it is not too much of an overhead. |
90 |
first = ((myTime - modelstart) .lt. 0.5*modelstep) |
91 |
changed = .FALSE. |
92 |
fac = 1. _d 0 |
93 |
count0 = 1 |
94 |
count1 = count0 |
95 |
c Give these variables some unproblematic values although they are |
96 |
c never used in this context. |
97 |
year0 = 0 |
98 |
year1 = year0 |
99 |
else |
100 |
c fldperiod .ne. 0 |
101 |
if (.not.usefldyearlyfields) then |
102 |
|
103 |
c Determine offset in seconds from beginning of input data |
104 |
c to current date. |
105 |
fldsectot = myTime - fldstartdate |
106 |
|
107 |
c Determine the flux records just before and after mycurrentdate. |
108 |
if ( repeatPeriod .eq. 0. _d 0 ) then |
109 |
|
110 |
if ( fldsectot .lt. 0. _d 0 ) then |
111 |
WRITE(msgBuf,'(2A)') 'EXF_GetFFieldRec: ', |
112 |
& 'myTime earlier than 1rst reccord (field-startdate)' |
113 |
CALL PRINT_ERROR( msgBuf, myThid ) |
114 |
STOP 'ABNORMAL END: S/R EXF_GetFFieldRec' |
115 |
endif |
116 |
count0 = int((fldsectot+0.5)/fldperiod) + 1 |
117 |
count1 = count0 + 1 |
118 |
fldsecs = mod(fldsectot,fldperiod) |
119 |
|
120 |
else |
121 |
c if ( repeatPeriod .gt. 0. ) |
122 |
|
123 |
c If using repeating data then make fldsectot cycle around. |
124 |
if(fldsectot.lt.0. _d 0) fldsectot = fldsectot + repeatPeriod |
125 |
fldsecs0 = mod(fldsectot,repeatPeriod) |
126 |
count0 = int((fldsecs0+0.5)/fldperiod) + 1 |
127 |
fldsecs1 = mod(fldsectot+fldperiod,repeatPeriod) |
128 |
count1 = int((fldsecs1+0.5)/fldperiod) + 1 |
129 |
fldsecs = mod(fldsecs0,fldperiod) |
130 |
|
131 |
endif |
132 |
|
133 |
c Weight belonging to count0 for linear interpolation purposes. |
134 |
fac = 1. - fldsecs/fldperiod |
135 |
|
136 |
else |
137 |
c if (usefldyearlyfields) |
138 |
|
139 |
c Determine seconds from beginning of year to model current time. |
140 |
call cal_GetDate( myIter, myTime, mydate, myThid ) |
141 |
year0 = int(mydate(1)/10000.) |
142 |
yearStartDate(1) = year0 * 10000 + 101 |
143 |
yearStartDate(2) = 0 |
144 |
yearStartDate(3) = mydate(3) |
145 |
yearStartDate(4) = mydate(4) |
146 |
CALL cal_TimePassed(yearStartDate,mydate,difftime,myThid) |
147 |
CALL cal_ToSeconds (difftime,myDateSeconds,myThid) |
148 |
|
149 |
c Determine the flux year just before mycurrentdate. |
150 |
if ( myDateSeconds .lt. fldstartdate ) year0 = year0 - 1 |
151 |
|
152 |
c Determine seconds in the flux year just before mycurrentdate. |
153 |
secondsInYear = ndaysnoleap * secondsperday |
154 |
if ( cal_IsLeap(year0,myThid) .eq. 2) |
155 |
& secondsInYear = ndaysleap * secondsperday |
156 |
|
157 |
c Determine the record just before mycurrentdate. |
158 |
if ( myDateSeconds .lt. fldstartdate ) |
159 |
& myDateSeconds = myDateSeconds + secondsInYear |
160 |
fldsectot = myDateSeconds - fldstartdate |
161 |
count0 = int((fldsectot+0.5)/fldperiod) + 1 |
162 |
|
163 |
c Determine the flux year and record just after mycurrentdate. |
164 |
year1 = year0 |
165 |
count1 = count0 + 1 |
166 |
if ( (fldstartdate+count0*fldperiod) .ge. secondsInYear ) then |
167 |
year1 = year0 + 1 |
168 |
count1 = 1 |
169 |
endif |
170 |
|
171 |
c Weight belonging to count0 for linear interpolation purposes. |
172 |
fldsecs = mod(fldsectot,fldperiod) |
173 |
fac = 1. - fldsecs/fldperiod |
174 |
if ( year0 .ne. year1 ) |
175 |
& fac = 1. - fldsecs/(secondsInYear-(count0-1)*fldperiod) |
176 |
|
177 |
endif |
178 |
c if (usefldyearlyfields) |
179 |
|
180 |
c Set switch for reading new record. |
181 |
if ( fldsecs - modelstep .lt. 0. _d 0 ) changed = .TRUE. |
182 |
|
183 |
endif |
184 |
c if (fldperiod .eq. 0.) |
185 |
|
186 |
RETURN |
187 |
END |