1 |
cnh |
1.1 |
! $Header: $ |
2 |
|
|
! $Name: $ |
3 |
|
|
|
4 |
|
|
MODULE SRDIAGS_MANAGER |
5 |
|
|
! |
6 |
|
|
! SR_DIAGS provides sub-region diagnostic accumulation for logically |
7 |
|
|
! rectangular meshes. |
8 |
|
|
! In MITgcm it is called from within DIAGS. |
9 |
|
|
! SR_DIAGS allocates buffers for saving sub-region data for particular fields |
10 |
|
|
! These buffers need to be allocated by the threads that will write to |
11 |
|
|
! them. Buffers are visible for read access across threads to allow for sinlge |
12 |
|
|
! threade I/O and communication - yucky..... |
13 |
|
|
! |
14 |
|
|
USE SRDIAGS_TYPES |
15 |
|
|
|
16 |
|
|
INTERFACE SRDIAG_FILL |
17 |
|
|
MODULE PROCEDURE SRDIAG_FILL_R8XYZ |
18 |
|
|
END INTERFACE |
19 |
|
|
|
20 |
|
|
CONTAINS |
21 |
|
|
|
22 |
|
|
SUBROUTINE SRDIAG_ADD_FCODE( fCode, offset, dAttr, diagVar, |
23 |
|
|
I mFactor, |
24 |
|
|
& myThid ) |
25 |
|
|
! |
26 |
|
|
! Add a field code to a SRDIAGS set |
27 |
|
|
! Indices for this field code will use offset "offset". |
28 |
|
|
! |
29 |
|
|
! == Routine arguments == |
30 |
|
|
CHARACTER*(*) fCode |
31 |
|
|
INTEGER offset(3) |
32 |
|
|
CHARACTER*(*) dAttr |
33 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
34 |
|
|
INTEGER myThid, nCodes |
35 |
|
|
REAL*8 mFactor |
36 |
|
|
|
37 |
|
|
! == Local variables == |
38 |
|
|
TYPE(SRDIAG_FCODE), POINTER :: tempCL(:) |
39 |
|
|
|
40 |
|
|
! |
41 |
|
|
! Expand list |
42 |
|
|
! |
43 |
|
|
diagVar%nCodes = diagVar%nCodes+1 |
44 |
|
|
nCodes = diagVar%nCodes |
45 |
|
|
IF ( nCodes .EQ. 1 ) THEN |
46 |
|
|
ALLOCATE( diagVar%cList(1) ) |
47 |
|
|
ELSE |
48 |
|
|
ALLOCATE( tempCL(nCodes-1) ) |
49 |
|
|
tempCL = diagVar%cList |
50 |
|
|
DEALLOCATE( diagVar%cList ) |
51 |
|
|
ALLOCATE( diagVar%cList(nCodes) ) |
52 |
|
|
diagVar%cList(1:nCodes-1) = tempCL |
53 |
|
|
DEALLOCATE( tempCL ) |
54 |
|
|
ENDIF |
55 |
|
|
! |
56 |
|
|
! Add entry |
57 |
|
|
! |
58 |
|
|
diagVar%cList(nCodes)%fCode = fCode |
59 |
|
|
diagVar%cList(nCodes)%dAttr = dAttr |
60 |
|
|
diagVar%cList(nCodes)%iOffset = offset(1) |
61 |
|
|
diagVar%cList(nCodes)%jOffset = offset(2) |
62 |
|
|
diagVar%cList(nCodes)%kOffset = offset(3) |
63 |
|
|
diagVar%cList(nCodes)%mFactor = mFactor |
64 |
|
|
|
65 |
|
|
RETURN |
66 |
|
|
END SUBROUTINE |
67 |
|
|
|
68 |
|
|
SUBROUTINE SRDIAG_ADD_REGION( |
69 |
|
|
I myLoI, myLoJ, myLoK, |
70 |
|
|
I myNI, myNJ, myNK, |
71 |
|
|
I iLo, jLo, kLo, |
72 |
|
|
I nI, nJ, nK, |
73 |
|
|
U diagVar, |
74 |
|
|
I myThid ) |
75 |
|
|
! |
76 |
|
|
! Add a simple region to a DIAG type variable |
77 |
|
|
! |
78 |
|
|
! Lots still to be done..... |
79 |
|
|
! DIAGS specification file must have been read before SR_DIAG_CREATE is called. |
80 |
|
|
! |
81 |
|
|
! Here we create masks for each of the index sets specified in the sub-region set. |
82 |
|
|
! These masks can be do loop regions, scatters, broken lines etc... |
83 |
|
|
|
84 |
|
|
! o do loop regions are specified in the input using [start:stride:end] or [v1 v2 v3] sets |
85 |
|
|
! of values. |
86 |
|
|
! o not sure how we specify scatters and broken lines in input yet. probably using |
87 |
|
|
! { } for point lists instead of [ ] for loops. |
88 |
|
|
! Note - { } point lists for a single region specification have to all be the same size. |
89 |
|
|
! - e.g. |
90 |
|
|
! {1 3 5}{7 4 8}[1 2] would give |
91 |
|
|
! for k=1:2 |
92 |
|
|
! for lp=1:3 |
93 |
|
|
! pt=[il(1), jl(1), k] |
94 |
|
|
! end |
95 |
|
|
! end |
96 |
|
|
! - whereas |
97 |
|
|
! [1 3 5][7 4 8][1 2] would give |
98 |
|
|
! for k=1:2 |
99 |
|
|
! for j=[7 4 8] |
100 |
|
|
! for i=[1 3 5] |
101 |
|
|
! pt=[i, j, k] |
102 |
|
|
! end |
103 |
|
|
! end |
104 |
|
|
! end |
105 |
|
|
! |
106 |
|
|
|
107 |
|
|
! -- Routine arguments -- |
108 |
|
|
! myLoI :: Offset from origin for this part of the mask. |
109 |
|
|
! myLoJ :: Offset from origin for this part of the mask. |
110 |
|
|
! myLoK :: Offset from origin for this part of the mask. |
111 |
|
|
! myNi :: Number cells in I for this part of the mask. |
112 |
|
|
! myNj :: Number cells in J for this part of the mask. |
113 |
|
|
! myNk :: Number cells in K for this part of the mask. |
114 |
|
|
! iLo :: Base coordinate in I for subregion. |
115 |
|
|
! jLo :: Base coordinate in J for subregion. |
116 |
|
|
! kLo :: Base coordinate in K for subregion. |
117 |
|
|
! nI :: Number of cells in I for subregion. |
118 |
|
|
! nJ :: Number of cells in J for subregion. |
119 |
|
|
! nK :: Number of cells in K for subregion. |
120 |
|
|
! diagVar :: Diagnostics structure to add region to. |
121 |
|
|
! myThid :: Id number of the thread making this call. |
122 |
|
|
INTEGER myLoI |
123 |
|
|
INTEGER myLoJ |
124 |
|
|
INTEGER myLoK |
125 |
|
|
INTEGER myNi |
126 |
|
|
INTEGER myNj |
127 |
|
|
INTEGER myNk |
128 |
|
|
INTEGER iLo |
129 |
|
|
INTEGER jLo |
130 |
|
|
INTEGER kLo |
131 |
|
|
INTEGER nI |
132 |
|
|
INTEGER nJ |
133 |
|
|
INTEGER nK |
134 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
135 |
|
|
INTEGER myThid |
136 |
|
|
|
137 |
|
|
! -- Local variables -- |
138 |
|
|
! |
139 |
|
|
TYPE(SRDIAG_MASK), POINTER :: tempML(:) |
140 |
|
|
INTEGER :: I, J, K |
141 |
|
|
INTEGER :: nPS |
142 |
|
|
! |
143 |
|
|
! Expand list |
144 |
|
|
diagVar%nPointSets = diagVar%nPointSets+1 |
145 |
|
|
nPS = diagVar%nPointSets |
146 |
|
|
IF ( nPS .EQ. 1 ) THEN |
147 |
|
|
ALLOCATE( diagVar%mList(1) ) |
148 |
|
|
ELSE |
149 |
|
|
ALLOCATE( tempML(nPS-1) ) |
150 |
|
|
tempML = diagVar%mList |
151 |
|
|
DEALLOCATE(diagVar%mList) |
152 |
|
|
ALLOCATE( diagVar%mList(nPS) ) |
153 |
|
|
diagVar%mList(1:nPS-1)=tempML |
154 |
|
|
DEALLOCATE(tempML) |
155 |
|
|
ENDIF |
156 |
|
|
! |
157 |
|
|
! Now add new diag |
158 |
|
|
! o create mask for this instance |
159 |
|
|
! for now this mask has size of the region owned |
160 |
|
|
! by the instance. |
161 |
|
|
ALLOCATE( |
162 |
|
|
& diagVar%mList(nPS)%mask( |
163 |
|
|
& myLoI:myLoI+myNI-1, |
164 |
|
|
& myLoJ:myLoJ+myNJ-1, |
165 |
|
|
& myLoK:myLoK+myNK-1 |
166 |
|
|
& ) |
167 |
|
|
&) |
168 |
|
|
diagVar%mList(nPS)%mask = .FALSE. |
169 |
|
|
DO K=myLoK,myLoK+myNK-1 |
170 |
|
|
IF ( K .GE. kLo .AND. K .LE. kLo+nK-1 ) THEN |
171 |
|
|
DO J=myLoJ,myLoJ+myNJ-1 |
172 |
|
|
IF ( J .GE. jLo .AND. J .LE. jLo+nJ-1 ) THEN |
173 |
|
|
DO I=myLoI,myLoI+myNI-1 |
174 |
|
|
IF ( I .GE. iLo .AND. I .LE. iLo+nI-1 ) THEN |
175 |
|
|
diagVar%mList(nPS)%mask(I,J,K) = .TRUE. |
176 |
|
|
! PRINT *, ' HELLO -1', myThid,I,J,K |
177 |
|
|
ENDIF |
178 |
|
|
ENDDO |
179 |
|
|
ENDIF |
180 |
|
|
ENDDO |
181 |
|
|
ENDIF |
182 |
|
|
ENDDO |
183 |
|
|
diagVar%mList(nPS)%nX = nI |
184 |
|
|
diagVar%mList(nPS)%nY = nJ |
185 |
|
|
diagVar%mList(nPS)%nR = nK |
186 |
|
|
diagVar%mList(nPS)%iLo = iLo |
187 |
|
|
diagVar%mList(nPS)%jLo = jLo |
188 |
|
|
diagVar%mList(nPS)%kLo = kLo |
189 |
|
|
|
190 |
|
|
RETURN |
191 |
|
|
END SUBROUTINE |
192 |
|
|
|
193 |
|
|
SUBROUTINE SRDIAG_CREATE( diagVar, aveFreq, outName, myThid ) |
194 |
|
|
! |
195 |
|
|
! Create a sub-region diagnostics spec object |
196 |
|
|
! |
197 |
|
|
! == Routine arguments == |
198 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
199 |
|
|
REAL*8 :: aveFreq |
200 |
|
|
CHARACTER*(*) :: outName |
201 |
|
|
INTEGER myThid |
202 |
|
|
|
203 |
|
|
! == Local variables == |
204 |
|
|
INTEGER iUnit |
205 |
|
|
|
206 |
|
|
ALLOCATE( diagVar ) |
207 |
|
|
diagVar%nPointSets = 0 |
208 |
|
|
diagVar%nCodes = 0 |
209 |
|
|
diagVar%aPeriod = aveFreq |
210 |
|
|
WRITE( diagVar%outName, '(A,A,I4.4)' ) TRIM(outName),'.',myThid |
211 |
|
|
NULLIFY(diagVar%bList) |
212 |
|
|
NULLIFY(diagVar%cList) |
213 |
|
|
|
214 |
|
|
! Clear the output file |
215 |
|
|
CALL MDSFINDUNIT( iUnit, myThid ) |
216 |
|
|
OPEN(unit=iUnit,file=TRIM(diagVar%outName), |
217 |
|
|
& FORM='unformatted',STATUS='NEW') |
218 |
|
|
CLOSE(iUnit) |
219 |
|
|
|
220 |
|
|
RETURN |
221 |
|
|
END SUBROUTINE |
222 |
|
|
|
223 |
|
|
SUBROUTINE SRDIAG_FILL_R8XYZ( fld, alpha, fCode, diagVar, myThid ) |
224 |
|
|
! == Routine arguments == |
225 |
|
|
REAL*8 :: fld(:,:,:) |
226 |
|
|
REAL*8 :: alpha |
227 |
|
|
CHARACTER*(*) :: fCode |
228 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
229 |
|
|
INTEGER :: myThid |
230 |
|
|
|
231 |
|
|
! == Local variables == |
232 |
|
|
INTEGER :: nRegs, nBufs |
233 |
|
|
INTEGER :: I, J, K, rC, thisCodeRank, NR |
234 |
|
|
INTEGER :: iB |
235 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: myBufs(:) |
236 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: myBuf |
237 |
|
|
INTEGER :: iLoFld, jLoFld, kLoFld |
238 |
|
|
INTEGER :: iHiFld, jHiFld, kHiFld |
239 |
|
|
INTEGER :: iLo, iHi, jLo, jHi, kLo, kHi |
240 |
|
|
INTEGER :: iLoMsk, iHiMsk |
241 |
|
|
INTEGER :: jLoMsk, jHiMsk |
242 |
|
|
INTEGER :: kLoMsk, kHiMsk |
243 |
|
|
INTEGER :: iFld, jFld, kFld |
244 |
|
|
! |
245 |
|
|
! PRINT *, 'HELLO 1' |
246 |
|
|
|
247 |
|
|
! Determine the field code rank for the field code fCode within subregion diagVar. |
248 |
|
|
CALL SRDIAG_GET_FIELD_CODE_RANK( |
249 |
|
|
I fCode, diagVar, |
250 |
|
|
O thisCodeRank, |
251 |
|
|
I myThid ) |
252 |
|
|
IF ( thisCodeRank .EQ. 0 ) RETURN |
253 |
|
|
! PRINT *, 'HELLO 2' |
254 |
|
|
|
255 |
|
|
! Look for an existing buffer for this code (for each region in turn |
256 |
|
|
! so that we find out if there are regions with no buffers). |
257 |
|
|
! If buffer is found we will use that buffer, otherwise we will create it. |
258 |
|
|
nRegs = diagVar%nPointSets |
259 |
|
|
iLoFld = LBOUND(fld,1)+diagVar%cList(thisCodeRank)%iOffset |
260 |
|
|
jLoFld = LBOUND(fld,2)+diagVar%cList(thisCodeRank)%jOffset |
261 |
|
|
kLoFld = LBOUND(fld,3)+diagVar%cList(thisCodeRank)%kOffset |
262 |
|
|
iHiFld = UBOUND(fld,1)+diagVar%cList(thisCodeRank)%iOffset |
263 |
|
|
jHiFld = UBOUND(fld,2)+diagVar%cList(thisCodeRank)%jOffset |
264 |
|
|
kHiFld = UBOUND(fld,3)+diagVar%cList(thisCodeRank)%kOffset |
265 |
|
|
! PRINT *, 'HELLO 3', iLoFld, iHiFld, TRIM(fCode) |
266 |
|
|
! PRINT *, 'HELLO 3', jLoFld, jHiFld, TRIM(fCode) |
267 |
|
|
! PRINT *, 'HELLO 3', kLoFld, kHiFld, TRIM(fCode) |
268 |
|
|
DO NR=1,nRegs |
269 |
|
|
! Find the buffer for region I and field code with rank thisCodeRank |
270 |
|
|
NULLIFY(myBuf) |
271 |
|
|
CALL SRDIAG_GET_DATA_BUFFER( thisCodeRank, NR, diagVar, |
272 |
|
|
I iLoFld, jLoFld, kLoFld, |
273 |
|
|
I iHiFld, jHiFld, kHiFld, |
274 |
|
|
O myBuf, |
275 |
|
|
I myThid ) |
276 |
|
|
! Now do masked add of data to the subregion buffer pointed to by myBuf |
277 |
|
|
! PRINT *, 'HELLO 4 REGION', NR, TRIM(fCode) |
278 |
|
|
iB = 0 |
279 |
|
|
iLoMsk = LBOUND(diagVar%mList(NR)%mask,1) |
280 |
|
|
iLo = MAX(iLoFld, iLoMsk ) |
281 |
|
|
iHiMsk = UBOUND(diagVar%mList(NR)%mask,1) |
282 |
|
|
iHi = MIN(iHiFld, iHiMsk ) |
283 |
|
|
|
284 |
|
|
jLoMsk = LBOUND(diagVar%mList(NR)%mask,2) |
285 |
|
|
jLo = MAX(jLoFld, jLoMsk ) |
286 |
|
|
jHiMsk = UBOUND(diagVar%mList(NR)%mask,2) |
287 |
|
|
jHi = MIN(jHiFld, jHiMsk ) |
288 |
|
|
|
289 |
|
|
kLoMsk = LBOUND(diagVar%mList(NR)%mask,3) |
290 |
|
|
kLo = MAX(kLoFld, kLoMsk ) |
291 |
|
|
kHiMsk = UBOUND(diagVar%mList(NR)%mask,3) |
292 |
|
|
kHi = MIN(kHiFld, kHiMsk ) |
293 |
|
|
! PRINT *, 'HELLO 4 kLo, kHi', kLo, kHi |
294 |
|
|
! PRINT *, 'HELLO 4 jLo, jHi', jLo, jHi |
295 |
|
|
! PRINT *, 'HELLO 4 iLo, iHi', iLo, iHi |
296 |
|
|
DO K=kLo,kHi |
297 |
|
|
DO J=jLo,jHi |
298 |
|
|
DO I=iLo,iHi |
299 |
|
|
IF ( diagVar%mList(NR)%mask(I,J,K) .EQV. .TRUE. ) |
300 |
|
|
& THEN |
301 |
|
|
iFld=I-diagVar%cList(thisCodeRank)%iOffset |
302 |
|
|
jFld=J-diagVar%cList(thisCodeRank)%jOffset |
303 |
|
|
kFld=K-diagVar%cList(thisCodeRank)%kOffset |
304 |
|
|
iB =iB+1 |
305 |
|
|
! PRINT *, ' HELLO 7 ADDING TO BUFFER', myThid,iFld,jFld,kFld |
306 |
|
|
myBuf%r8Values(iB) = myBuf%r8Values(iB)+ |
307 |
|
|
& fld(iFld,jFld,kFld) |
308 |
|
|
& *alpha*diagVar%cList(thisCodeRank)%mFactor |
309 |
|
|
! PRINT *, ' HELLO 7 ADDED TO BUFFER', myThid,iFld,jFld,kFld |
310 |
|
|
ENDIF |
311 |
|
|
ENDDO |
312 |
|
|
ENDDO |
313 |
|
|
ENDDO |
314 |
|
|
ENDDO |
315 |
|
|
|
316 |
|
|
! PRINT *, 'HELLO 4 LEAVING FIELD ADD' |
317 |
|
|
|
318 |
|
|
RETURN |
319 |
|
|
END SUBROUTINE |
320 |
|
|
|
321 |
|
|
SUBROUTINE SRDIAG_GET_DATA_BUFFER( thisCodeRank, thisRegionRank, |
322 |
|
|
I diagVar, |
323 |
|
|
I iLoFld, |
324 |
|
|
I jLoFld, |
325 |
|
|
I kLoFld, |
326 |
|
|
I iHiFld, |
327 |
|
|
I jHiFld, |
328 |
|
|
I kHiFld, |
329 |
|
|
O theBuf, |
330 |
|
|
I myThid ) |
331 |
|
|
! Search through sub-region specification diagVar for data buffer |
332 |
|
|
! associated with the region with region rank "thisRegionRank" and the field code with |
333 |
|
|
! field code rank "thisCodeRank". |
334 |
|
|
! Return pointer to the buffer, creating the buffer if need be. |
335 |
|
|
! == Routine arguments == |
336 |
|
|
INTEGER :: thisCodeRank |
337 |
|
|
INTEGER :: thisRegionRank |
338 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
339 |
|
|
INTEGER :: iLoFld |
340 |
|
|
INTEGER :: jLoFld |
341 |
|
|
INTEGER :: kLoFld |
342 |
|
|
INTEGER :: iHiFld |
343 |
|
|
INTEGER :: jHiFld |
344 |
|
|
INTEGER :: kHiFld |
345 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: theBuf |
346 |
|
|
INTEGER :: myThid |
347 |
|
|
|
348 |
|
|
! == Local variables == |
349 |
|
|
INTEGER :: nRegs, nBufs, I, J, K, nCells |
350 |
|
|
INTEGER :: iLo, iHi, iLoMsk, iHiMsk |
351 |
|
|
INTEGER :: jLo, jHi, jLoMsk, jHiMsk |
352 |
|
|
INTEGER :: kLo, kHi, kLoMsk, kHiMsk |
353 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: dBufs(:) |
354 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: tempBList(:) |
355 |
|
|
|
356 |
|
|
! PRINT *, 'HELLO 4 GET_DATA_BUFFER', thisCodeRank, thisRegionRank |
357 |
|
|
! |
358 |
|
|
CALL SRDIAG_GET_DATA_BUFFER_NOCREATE( |
359 |
|
|
I thisCodeRank, thisRegionRank, diagVar, |
360 |
|
|
O theBuf, |
361 |
|
|
I myThid ) |
362 |
|
|
! |
363 |
|
|
! If we didn't find a buffer we need to create it |
364 |
|
|
IF ( .NOT. ASSOCIATED(theBuf) ) THEN |
365 |
|
|
! First need to figure out how big the buffer needs to be |
366 |
|
|
! We have two sets of indices |
367 |
|
|
! fld (iLoFld:iHiFld,jLoFld:jHiFld,kLoFld:kHiFld) and |
368 |
|
|
! mask(iLo:iLo+nX-1,jLo:jLo+nY-1,kLo:kLo+nR-1) |
369 |
|
|
! the number of cells we will have in buffer is the number of |
370 |
|
|
! mask values that are true in the fld index range. However, |
371 |
|
|
! we _must_not_ simpy reference mask with fld index ranges |
372 |
|
|
! because they may lie outside the valid index range for mask. |
373 |
|
|
nCells = 0 |
374 |
|
|
iLoMsk = LBOUND(diagVar%mList(thisRegionRank)%mask,1) |
375 |
|
|
iLo = MAX(iLoFld, iLoMsk ) |
376 |
|
|
iHiMsk = UBOUND(diagVar%mList(thisRegionRank)%mask,1) |
377 |
|
|
iHi = MIN(iHiFld, iHiMsk ) |
378 |
|
|
|
379 |
|
|
jLoMsk = LBOUND(diagVar%mList(thisRegionRank)%mask,2) |
380 |
|
|
jLo = MAX(jLoFld, jLoMsk ) |
381 |
|
|
jHiMsk = UBOUND(diagVar%mList(thisRegionRank)%mask,2) |
382 |
|
|
jHi = MIN(jHiFld, jHiMsk ) |
383 |
|
|
|
384 |
|
|
kLoMsk = LBOUND(diagVar%mList(thisRegionRank)%mask,3) |
385 |
|
|
kLo = MAX(kLoFld, kLoMsk ) |
386 |
|
|
kHiMsk = UBOUND(diagVar%mList(thisRegionRank)%mask,3) |
387 |
|
|
kHi = MIN(kHiFld, kHiMsk ) |
388 |
|
|
DO K=kLo,kHi |
389 |
|
|
DO J=jLo,jHi |
390 |
|
|
DO I=iLo,iHi |
391 |
|
|
IF ( diagVar%mList(thisRegionRank)%mask(I,J,K) .EQV. .TRUE. ) |
392 |
|
|
& THEN |
393 |
|
|
nCells = nCells+1 |
394 |
|
|
ENDIF |
395 |
|
|
ENDDO |
396 |
|
|
ENDDO |
397 |
|
|
ENDDO |
398 |
|
|
! PRINT *, 'HELLO 4 iLo, iHi = ', iLo, iHi |
399 |
|
|
! PRINT *, 'HELLO 4 jLo, jHi = ', jLo, jHi |
400 |
|
|
! PRINT *, 'HELLO 4 kLo, kHi = ', kLo, kHi |
401 |
|
|
! PRINT *, 'HELLO 4 nCells = ', nCells, thisRegionRank,thisCodeRank |
402 |
|
|
! Add a new entry at the end of the sub-region buffer list |
403 |
|
|
IF ( ASSOCIATED(diagVar%bList) ) THEN |
404 |
|
|
! List is not empty so we need to increase its size |
405 |
|
|
nBufs = UBOUND(diagVar%bList,1) |
406 |
|
|
ALLOCATE(tempBList(nBufs)) |
407 |
|
|
tempBList = diagVar%bList |
408 |
|
|
DEALLOCATE(diagVar%bList) |
409 |
|
|
ALLOCATE(diagVar%bList(nBufs+1)) |
410 |
|
|
diagVar%bList(1:nBufs) = tempBList |
411 |
|
|
ALLOCATE(theBuf) |
412 |
|
|
diagVar%bList(nBufs+1) = theBuf |
413 |
|
|
ELSE |
414 |
|
|
! List is empty so we create for first time |
415 |
|
|
ALLOCATE(diagVar%bList(1)) |
416 |
|
|
ALLOCATE(theBuf) |
417 |
|
|
diagVar%bList(1) = theBuf |
418 |
|
|
ENDIF |
419 |
|
|
|
420 |
|
|
! Now fill out the new buffer (which is at the end of the list) |
421 |
|
|
nBufs = UBOUND(diagVar%bList,1) |
422 |
|
|
! Add ranks and initial flags |
423 |
|
|
diagVar%bList(nBufs)%metaWritten = .FALSE. |
424 |
|
|
diagVar%bList(nBufs)%vType = SRDIAG_R8TYPE |
425 |
|
|
diagVar%bList(nBufs)%fCodeRank = thisCodeRank |
426 |
|
|
diagVar%bList(nBufs)%regionRank = thisRegionRank |
427 |
|
|
|
428 |
|
|
! Add data buffer to the entry at the end |
429 |
|
|
NULLIFY(diagVar%bList(nBufs)%r8Values) |
430 |
|
|
NULLIFY(diagVar%bList(nBufs)%r4Values) |
431 |
|
|
NULLIFY(diagVar%bList(nBufs)%iValues) |
432 |
|
|
IF ( nCells .GT. 0 ) THEN |
433 |
|
|
ALLOCATE(diagVar%bList(nBufs)%r8Values(nCells) ) |
434 |
|
|
! For a newly allocated buffer we set the initial value to zero |
435 |
|
|
diagVar%bList(nBufs)%r8Values = 0. |
436 |
|
|
ENDIF |
437 |
|
|
theBuf => diagVar%bList(nBufs) |
438 |
|
|
ENDIF |
439 |
|
|
|
440 |
|
|
RETURN |
441 |
|
|
END SUBROUTINE |
442 |
|
|
|
443 |
|
|
SUBROUTINE SRDIAG_GET_DATA_BUFFER_NOCREATE( thisCodeRank, |
444 |
|
|
I thisRegionRank, |
445 |
|
|
I diagVar, |
446 |
|
|
O theBuf, |
447 |
|
|
I myThid ) |
448 |
|
|
! Search through sub-region specification diagVar for data buffer |
449 |
|
|
! associated with the region with region rank "thisRegionRank" and the field code with |
450 |
|
|
! field code rank "thisCodeRank". |
451 |
|
|
! Return pointer to the buffer. |
452 |
|
|
! == Routine arguments == |
453 |
|
|
INTEGER :: thisCodeRank |
454 |
|
|
INTEGER :: thisRegionRank |
455 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
456 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: theBuf |
457 |
|
|
INTEGER :: myThid |
458 |
|
|
|
459 |
|
|
! == Local variables == |
460 |
|
|
INTEGER :: nRegs, nBufs, I, J |
461 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: dBufs(:) |
462 |
|
|
|
463 |
|
|
! |
464 |
|
|
NULLIFY(theBuf) |
465 |
|
|
nRegs = diagVar%nPointSets |
466 |
|
|
IF ( ASSOCIATED(diagVar%bList) ) THEN |
467 |
|
|
DO J=1,nRegs |
468 |
|
|
dBufs => diagVar%bList |
469 |
|
|
nBufs = UBOUND( dBufs,1 ) |
470 |
|
|
! Work through the buffers |
471 |
|
|
DO I=1,nBufs |
472 |
|
|
! Select buffers associated with this codes rank |
473 |
|
|
IF ( diagVar%bList(I)%fCodeRank .EQ. thisCodeRank .AND. |
474 |
|
|
& diagVar%bList(I)%regionRank .EQ. thisRegionRank ) THEN |
475 |
|
|
! PRINT *, 'FOUND BUFFER FOR rank, code', thisCodeRank, |
476 |
|
|
! & thisRegionRank |
477 |
|
|
theBuf => diagVar%bList(I) |
478 |
|
|
ENDIF |
479 |
|
|
ENDDO |
480 |
|
|
ENDDO |
481 |
|
|
ENDIF |
482 |
|
|
! |
483 |
|
|
RETURN |
484 |
|
|
END SUBROUTINE |
485 |
|
|
|
486 |
|
|
SUBROUTINE SRDIAG_GET_FIELD_CODE_RANK( |
487 |
|
|
I fCode, diagVar, |
488 |
|
|
O thisCodeRank, |
489 |
|
|
I myThid ) |
490 |
|
|
|
491 |
|
|
! == Routine arguments == |
492 |
|
|
CHARACTER*(*) :: fCode |
493 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
494 |
|
|
INTEGER :: thisCodeRank |
495 |
|
|
INTEGER :: myThid |
496 |
|
|
|
497 |
|
|
! == Local variables == |
498 |
|
|
INTEGER :: I |
499 |
|
|
|
500 |
|
|
thisCodeRank = 0 |
501 |
|
|
IF ( ASSOCIATED(diagVar%cList) ) THEN |
502 |
|
|
DO I=1,UBOUND(diagVar%cList,1) |
503 |
|
|
IF ( diagVar%cList(I)%fCode .EQ. fCode ) THEN |
504 |
|
|
thisCodeRank = I |
505 |
|
|
ENDIF |
506 |
|
|
ENDDO |
507 |
|
|
ENDIF |
508 |
|
|
|
509 |
|
|
RETURN |
510 |
|
|
END SUBROUTINE |
511 |
|
|
|
512 |
|
|
SUBROUTINE SRDIAG_INIT( myThid ) |
513 |
|
|
! |
514 |
|
|
! Initialize the SR_DIAGS package |
515 |
|
|
! Doesn't do anything! |
516 |
|
|
! |
517 |
|
|
! myThid :: Thread rank |
518 |
|
|
INTEGER myThid |
519 |
|
|
|
520 |
|
|
RETURN |
521 |
|
|
END SUBROUTINE |
522 |
|
|
|
523 |
|
|
SUBROUTINE SRDIAG_SCALE( alpha, fCode, diagVar, myThid ) |
524 |
|
|
! == Routine arguments == |
525 |
|
|
REAL*8 :: alpha |
526 |
|
|
CHARACTER*(*) :: fCode |
527 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
528 |
|
|
INTEGER :: myThid |
529 |
|
|
|
530 |
|
|
! == Local variables == |
531 |
|
|
INTEGER :: nRegs, nBufs |
532 |
|
|
INTEGER :: I, J, rC, thisCodeRank, NR |
533 |
|
|
INTEGER :: iB |
534 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: myBufs(:) |
535 |
|
|
TYPE(SRDIAG_BUFFER), POINTER :: myBuf |
536 |
|
|
INTEGER :: iLoFld, jLoFld, kLoFld |
537 |
|
|
INTEGER :: iHiFld, jHiFld, kHiFld |
538 |
|
|
INTEGER :: iLo, iHi, jLo, jHi, kLo, kHi |
539 |
|
|
|
540 |
|
|
! Determine the field code rank for the field code fCode within subregion diagVar. |
541 |
|
|
CALL SRDIAG_GET_FIELD_CODE_RANK( |
542 |
|
|
I fCode, diagVar, |
543 |
|
|
O thisCodeRank, |
544 |
|
|
I myThid ) |
545 |
|
|
IF ( thisCodeRank .EQ. 0 ) RETURN |
546 |
|
|
! PRINT *, ' HELLO 5 thisCodeRank = ', thisCodeRank, myThid |
547 |
|
|
|
548 |
|
|
! Look for existing buffers for this code for each region. |
549 |
|
|
nRegs = diagVar%nPointSets |
550 |
|
|
DO NR=1,nRegs |
551 |
|
|
! Find the buffer for region NR and field code with rank thisCodeRank |
552 |
|
|
CALL SRDIAG_GET_DATA_BUFFER_NOCREATE( thisCodeRank, NR, diagVar, |
553 |
|
|
O myBuf, |
554 |
|
|
I myThid ) |
555 |
|
|
! Now scale the buffer values |
556 |
|
|
IF ( ASSOCIATED(myBuf) ) THEN |
557 |
|
|
IF ( ASSOCIATED(myBuf%r8Values) ) THEN |
558 |
|
|
! PRINT *, ' HELLO 6 ASSOCIATED ', myThid |
559 |
|
|
myBuf%r8Values = myBuf%r8Values*alpha |
560 |
|
|
ELSE |
561 |
|
|
! PRINT *, ' HELLO 6 NOT ASSOCIATED ', myThid |
562 |
|
|
ENDIF |
563 |
|
|
ENDIF |
564 |
|
|
ENDDO |
565 |
|
|
|
566 |
|
|
RETURN |
567 |
|
|
END SUBROUTINE |
568 |
|
|
|
569 |
|
|
SUBROUTINE SRDIAG_STORE( diagVar, curTime, myThid ) |
570 |
|
|
TYPE(SRDIAG_SPEC), POINTER :: diagVar |
571 |
|
|
INTEGER :: myThid |
572 |
|
|
REAL*8 :: curTime |
573 |
|
|
|
574 |
|
|
INTEGER :: iUnit |
575 |
|
|
INTEGER :: NB |
576 |
|
|
INTEGER :: I, rr, fr, J |
577 |
|
|
INTEGER*8 :: iLo8, iHi8, jLo8, jHi8, |
578 |
|
|
& kLo8, kHi8 |
579 |
|
|
INTEGER*8 :: rr8 |
580 |
|
|
INTEGER*8 :: npt8 |
581 |
|
|
CHARACTER*512 :: fC512 |
582 |
|
|
INTEGER*4 :: dFlag4 |
583 |
|
|
|
584 |
|
|
CHARACTER*8 :: vString |
585 |
|
|
INTEGER :: dFPointsStruct |
586 |
|
|
INTEGER :: dFPointsUnStruct |
587 |
|
|
INTEGER :: dFData |
588 |
|
|
PARAMETER ( vString = 'v001 ', |
589 |
|
|
& dFPointsStruct = 0, |
590 |
|
|
& dFPointsUnStruct = 1, |
591 |
|
|
& dFData = 2 ) |
592 |
|
|
|
593 |
|
|
CALL MDSFINDUNIT( iUnit, myThid ) |
594 |
|
|
OPEN(unit=iUnit,file=TRIM(diagVar%outName), |
595 |
|
|
& FORM='unformatted',STATUS='OLD', |
596 |
|
|
& POSITION='APPEND') |
597 |
|
|
IF ( diagVar%vWritten .EQV. .FALSE. ) THEN |
598 |
|
|
WRITE(iunit) vString |
599 |
|
|
diagVar%vWritten = .TRUE. |
600 |
|
|
ENDIF |
601 |
|
|
IF ( .NOT. ASSOCIATED(diagVar%bList) ) THEN |
602 |
|
|
CLOSE( iUnit ) |
603 |
|
|
RETURN |
604 |
|
|
ENDIF |
605 |
|
|
! Need to store each code for each region |
606 |
|
|
! Use following format for data |
607 |
|
|
! "dflag4bytes" "fieldcode512bytes" "regionRank8bytes" "time8bytes" "npoints8bytes" (data8bytes) x npoints |
608 |
|
|
! On first write need to write index ranges for the code and region |
609 |
|
|
! (for scatter point set) |
610 |
|
|
! "dflag4bytes" "fieldcode512bytes" "regionRank8bytes" "avPeriodr8" "npoints8bytes" (ival8bytes jval8bytes kval8bytes) x npoints |
611 |
|
|
! -or- (for structured point set) |
612 |
|
|
! "dflag4bytes" "fieldcode512bytes" "regionRank8bytes" "avPeriod8" ilo8bytes ihi8bytes jlo8bytes jhi8bytes klo8bytes khi8bytes |
613 |
|
|
NB = UBOUND(diagVar%bList,1) |
614 |
|
|
DO I = 1, NB |
615 |
|
|
IF ( ASSOCIATED(diagVar%bList(I)%r8Values) ) THEN |
616 |
|
|
! This buffer has some data |
617 |
|
|
rr = diagVar%bList(I)%regionRank |
618 |
|
|
fr = diagVar%bList(I)%fCodeRank |
619 |
|
|
rr8 = rr |
620 |
|
|
npt8 = UBOUND(diagVar%bList(I)%r8Values,1) |
621 |
|
|
fC512 = TRIM(diagVar%cList(fr)%fCode) |
622 |
|
|
IF ( diagVar%bList(I)%metaWritten .EQV. .FALSE. ) THEN |
623 |
|
|
! Write meta data if it hasn't already been written |
624 |
|
|
iLo8 = MAX(LBOUND(diagVar%mList(rr)%mask,1), |
625 |
|
|
& diagVar%mList(rr)%iLo |
626 |
|
|
& ) |
627 |
|
|
iHi8 = MIN(UBOUND(diagVar%mList(rr)%mask,1), |
628 |
|
|
& diagVar%mList(rr)%iLo+ |
629 |
|
|
& diagVar%mList(rr)%nX-1 |
630 |
|
|
& ) |
631 |
|
|
jLo8 = MAX(LBOUND(diagVar%mList(rr)%mask,2), |
632 |
|
|
& diagVar%mList(rr)%jLo |
633 |
|
|
& ) |
634 |
|
|
jHi8 = MIN(UBOUND(diagVar%mList(rr)%mask,2), |
635 |
|
|
& diagVar%mList(rr)%jLo+ |
636 |
|
|
& diagVar%mList(rr)%nY-1 |
637 |
|
|
& ) |
638 |
|
|
kLo8 = MAX(LBOUND(diagVar%mList(rr)%mask,3), |
639 |
|
|
& diagVar%mList(rr)%kLo |
640 |
|
|
& ) |
641 |
|
|
kHi8 = MIN(UBOUND(diagVar%mList(rr)%mask,3), |
642 |
|
|
& diagVar%mList(rr)%kLo+ |
643 |
|
|
& diagVar%mList(rr)%nR-1 |
644 |
|
|
& ) |
645 |
|
|
WRITE(iUnit) dFPointsStruct, fC512, rr8, diagVar%aPeriod, |
646 |
|
|
& iLo8, iHi8, jLo8, jHi8, kLo8, kHi8 |
647 |
|
|
diagVar%bList(I)%metaWritten = .TRUE. |
648 |
|
|
ENDIF |
649 |
|
|
! Now write the data |
650 |
|
|
diagVar%bList(I)%r8Values= |
651 |
|
|
& diagVar%bList(I)%r8Values/diagVar%aPeriod |
652 |
|
|
WRITE(iUnit) dfData, fc512, rr8, curTime, npt8, |
653 |
|
|
& (diagVar%bList(I)%r8Values(J),J=1,npt8 ) |
654 |
|
|
diagVar%bList(I)%r8Values=0. |
655 |
|
|
! WRITE(iunit) 1.0 |
656 |
|
|
ENDIF |
657 |
|
|
ENDDO |
658 |
|
|
CLOSE(iUnit) |
659 |
|
|
|
660 |
|
|
RETURN |
661 |
|
|
END SUBROUTINE |
662 |
|
|
END MODULE |