1 |
C $Header: /u/gcmpack/MITgcm/pkg/flt/flt_up.F,v 1.12 2011/08/31 21:41:55 jmc Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "FLT_OPTIONS.h" |
5 |
|
6 |
CBOP 0 |
7 |
C !ROUTINE: FLT_UP |
8 |
|
9 |
C !INTERFACE: |
10 |
SUBROUTINE FLT_UP ( |
11 |
I myTime, myIter, myThid ) |
12 |
|
13 |
C !DESCRIPTION: |
14 |
C *==========================================================* |
15 |
C | SUBROUTINE FLT_UP |
16 |
C | o This routine moves particles vertical from the target |
17 |
C | depth to the surface and samples the model state over |
18 |
C | the full water column at horizontal float position |
19 |
C | every flt_int_prof time steps and writes output. |
20 |
C *==========================================================* |
21 |
|
22 |
C !USES: |
23 |
IMPLICIT NONE |
24 |
C == global variables == |
25 |
#include "SIZE.h" |
26 |
#include "EEPARAMS.h" |
27 |
#include "PARAMS.h" |
28 |
#include "DYNVARS.h" |
29 |
#include "FLT_SIZE.h" |
30 |
#include "FLT.h" |
31 |
#include "FLT_BUFF.h" |
32 |
|
33 |
C !INPUT PARAMETERS: |
34 |
C myTime :: current time in simulation |
35 |
C myIter :: current iteration number |
36 |
C myThid :: my Thread Id number |
37 |
_RL myTime |
38 |
INTEGER myIter, myThid |
39 |
|
40 |
C !FUNCTIONS: |
41 |
_RL FLT_MAP_K2R |
42 |
EXTERNAL FLT_MAP_K2R |
43 |
|
44 |
C !LOCAL VARIABLES: |
45 |
INTEGER bi, bj, nFlds |
46 |
INTEGER ip, k, ii |
47 |
INTEGER imax |
48 |
PARAMETER (imax=(9+4*Nr)) |
49 |
_RL tmp(imax) |
50 |
_RL ix, jy, i0x, j0y, xx, yy, zz |
51 |
_RL uu,vv,tt,ss, pp |
52 |
_RL npart_read, npart_times |
53 |
_RS dummyRS(1) |
54 |
INTEGER fp, ioUnit, irecord |
55 |
CHARACTER*(MAX_LEN_FNAM) fn |
56 |
CHARACTER*(MAX_LEN_MBUF) msgBuf |
57 |
CEOP |
58 |
|
59 |
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| |
60 |
|
61 |
C-- set number of fields to write |
62 |
nFlds = 0 |
63 |
IF ( flt_selectProfOutp.GE.1 ) nFlds = nFlds + 8 |
64 |
IF ( flt_selectProfOutp.GE.2 ) nFlds = nFlds + 1 + 4*Nr |
65 |
|
66 |
C-- check buffer size |
67 |
IF ( nFlds.GT.fltBufDim ) THEN |
68 |
_BEGIN_MASTER(myThid) |
69 |
WRITE(msgBuf,'(3(A,I4))') ' FLT_UP: fltBufDim=', fltBufDim, |
70 |
& ' too small (<', nFlds, ' )' |
71 |
CALL PRINT_ERROR( msgBuf, myThid ) |
72 |
WRITE(msgBuf,'(2A)') ' FLT_UP: => increase fltBufDim', |
73 |
& ' in "FLT_SIZE.h" & recompile' |
74 |
CALL PRINT_ERROR( msgBuf, myThid ) |
75 |
_END_MASTER(myThid) |
76 |
CALL ALL_PROC_DIE( myThid ) |
77 |
STOP 'ABNORMAL END: S/R FLT_UP' |
78 |
ENDIF |
79 |
|
80 |
IF ( myIter.EQ.nIter0 ) RETURN |
81 |
|
82 |
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| |
83 |
C-- Calculate position + other fields at float position and fill up IO-buffer |
84 |
|
85 |
DO bj=myByLo(myThid),myByHi(myThid) |
86 |
DO bi=myBxLo(myThid),myBxHi(myThid) |
87 |
|
88 |
i0x = DFLOAT( myXGlobalLo-1 + (bi-1)*sNx ) |
89 |
j0y = DFLOAT( myYGlobalLo-1 + (bj-1)*sNy ) |
90 |
DO ip=1,npart_tile(bi,bj) |
91 |
|
92 |
C Move float to the surface |
93 |
IF ( myTime.GE.tstart(ip,bi,bj) .AND. |
94 |
& (tend(ip,bi,bj).EQ.-1..OR.myTime.LE.tend(ip,bi,bj)) |
95 |
& .AND. |
96 |
& kpart(ip,bi,bj).EQ.kfloat(ip,bi,bj) .AND. |
97 |
& iup(ip,bi,bj).GT.0. |
98 |
& ) THEN |
99 |
|
100 |
IF ( MOD(myTime,iup(ip,bi,bj)).EQ.0.) |
101 |
& kpart(ip,bi,bj) = flt_surf |
102 |
|
103 |
ENDIF |
104 |
|
105 |
C If float has died move to level 0 |
106 |
IF ( tend(ip,bi,bj).NE.-1..AND.myTime.GT.tend(ip,bi,bj) |
107 |
& ) THEN |
108 |
kpart(ip,bi,bj) = 0. |
109 |
ENDIF |
110 |
|
111 |
IF ( flt_selectProfOutp.GE.1 ) THEN |
112 |
C Convert to coordinates |
113 |
ix = ipart(ip,bi,bj) |
114 |
jy = jpart(ip,bi,bj) |
115 |
CALL FLT_MAP_IJLOCAL2XY( xx, yy, |
116 |
I ix, jy, bi,bj, myThid ) |
117 |
zz = FLT_MAP_K2R( kpart(ip,bi,bj),bi,bj,myThid ) |
118 |
|
119 |
tmp(1) = npart(ip,bi,bj) |
120 |
tmp(2) = myTime |
121 |
tmp(3) = xx |
122 |
tmp(4) = yy |
123 |
tmp(5) = zz |
124 |
tmp(6) = ix + i0x |
125 |
tmp(7) = jy + j0y |
126 |
tmp(8) = kpart(ip,bi,bj) |
127 |
ENDIF |
128 |
|
129 |
IF ( ( flt_selectProfOutp.GE.2 ) .AND. |
130 |
& ( myTime.GE.tstart(ip,bi,bj) ) .AND. |
131 |
& ( tend(ip,bi,bj).EQ.-1..OR.myTime.LE.tend(ip,bi,bj) ) |
132 |
& ) THEN |
133 |
CALL FLT_BILINEAR2D(ix,jy,pp,etaN,0,bi,bj,myThid) |
134 |
tmp(9) = pp |
135 |
DO k=1,Nr |
136 |
CALL FLT_BILINEAR (ix,jy,uu,uVel, k,1,bi,bj,myThid) |
137 |
CALL FLT_BILINEAR (ix,jy,vv,vVel, k,2,bi,bj,myThid) |
138 |
CALL FLT_BILINEAR (ix,jy,tt,theta, k,0,bi,bj,myThid) |
139 |
CALL FLT_BILINEAR (ix,jy,ss,salt, k,0,bi,bj,myThid) |
140 |
tmp(9+k ) = uu |
141 |
tmp(9+k+1*Nr) = vv |
142 |
tmp(9+k+2*Nr) = tt |
143 |
tmp(9+k+3*Nr) = ss |
144 |
ENDDO |
145 |
ELSEIF ( flt_selectProfOutp.GE.2 ) THEN |
146 |
DO ii=9,nFlds |
147 |
tmp(ii) = flt_nan |
148 |
ENDDO |
149 |
ENDIF |
150 |
|
151 |
DO ii=1,nFlds |
152 |
flt_io_buff(ii,ip,bi,bj) = tmp(ii) |
153 |
ENDDO |
154 |
|
155 |
ENDDO |
156 |
|
157 |
ENDDO |
158 |
ENDDO |
159 |
|
160 |
IF ( flt_selectProfOutp.LE.0 ) RETURN |
161 |
|
162 |
C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| |
163 |
|
164 |
C-- Write shared buffer to file |
165 |
|
166 |
_BARRIER |
167 |
_BEGIN_MASTER(myThid) |
168 |
|
169 |
fn = 'float_profiles' |
170 |
fp = writeBinaryPrec |
171 |
|
172 |
DO bj=1,nSy |
173 |
DO bi=1,nSx |
174 |
|
175 |
C (1) read actual number floats from file (if exists) |
176 |
ioUnit = -2 |
177 |
CALL MDS_READVEC_LOC( fn, fp, ioUnit, 'RL', nFlds, |
178 |
& tmp, dummyRS, |
179 |
& bi, bj, 1, myThid ) |
180 |
IF ( ioUnit.GT. 0 ) THEN |
181 |
npart_read = tmp(1) |
182 |
npart_times = tmp(5) |
183 |
ii = NINT(tmp(7)) |
184 |
C- for backward compatibility with old profile files: |
185 |
IF ( ii.EQ.0 ) ii = 9+4*Nr |
186 |
IF ( ii.NE.nFlds ) THEN |
187 |
WRITE(msgBuf,'(A,I4,A)') |
188 |
& 'FLT_UP: nFlds=', nFlds,' different from' |
189 |
CALL PRINT_ERROR( msgBuf, myThid ) |
190 |
WRITE(msgBuf,'(3A,I4,A)') |
191 |
& 'previous file (',fn(1:14),') value =',ii |
192 |
CALL PRINT_ERROR( msgBuf, myThid ) |
193 |
CALL ALL_PROC_DIE( 0 ) |
194 |
STOP 'ABNORMAL END: S/R FLT_UP' |
195 |
ENDIF |
196 |
C- close the read-unit (safer to use a different unit for writing) |
197 |
CLOSE( ioUnit ) |
198 |
ELSE |
199 |
npart_read = 0. |
200 |
npart_times = 0. |
201 |
tmp(2) = myTime |
202 |
ENDIF |
203 |
|
204 |
C (2) write new actual number floats and time into file |
205 |
C- the standard routine mds_writevec_loc can be used here |
206 |
|
207 |
C total number of records in this file |
208 |
tmp(1) = DBLE(npart_tile(bi,bj))+npart_read |
209 |
C first time of writing floats (do not change when written) |
210 |
c tmp(2) = tmp(2) |
211 |
C current time |
212 |
tmp(3) = myTime |
213 |
C timestep |
214 |
tmp(4) = flt_int_prof |
215 |
C total number of timesteps |
216 |
tmp(5) = npart_times + 1. |
217 |
C total number of floats |
218 |
tmp(6) = max_npart |
219 |
C total number of fields |
220 |
tmp(7) = nFlds |
221 |
DO ii=8,nFlds |
222 |
tmp(ii) = 0. |
223 |
ENDDO |
224 |
ioUnit = -1 |
225 |
CALL MDS_WRITEVEC_LOC( fn, fp, ioUnit, 'RL', nFlds, |
226 |
& tmp, dummyRS, |
227 |
& bi, bj, -1, myIter, myThid ) |
228 |
|
229 |
DO ip=1,npart_tile(bi,bj) |
230 |
C (3) write float positions into file |
231 |
irecord = npart_read+ip+1 |
232 |
IF ( ip.NE.npart_tile(bi,bj) ) irecord = -irecord |
233 |
CALL MDS_WRITEVEC_LOC( fn, fp, ioUnit, 'RL', nFlds, |
234 |
& flt_io_buff(1,ip,bi,bj), dummyRS, |
235 |
& bi, bj, irecord, myIter, myThid ) |
236 |
ENDDO |
237 |
CLOSE( ioUnit ) |
238 |
|
239 |
ENDDO |
240 |
ENDDO |
241 |
|
242 |
_END_MASTER(myThid) |
243 |
_BARRIER |
244 |
|
245 |
RETURN |
246 |
END |