1 |
C $Header: /u/gcmpack/MITgcm/eesupp/src/exch_uv_rx_cube.template,v 1.6 2010/05/04 00:39:52 jmc Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "CPP_EEOPTIONS.h" |
5 |
|
6 |
CBOP |
7 |
C !ROUTINE: EXCH1_UV_RX_CUBE |
8 |
|
9 |
C !INTERFACE: |
10 |
SUBROUTINE EXCH1_UV_RX_CUBE( |
11 |
U Uarray, Varray, |
12 |
I withSigns, |
13 |
I myOLw, myOLe, myOLs, myOLn, myNz, |
14 |
I exchWidthX, exchWidthY, |
15 |
I cornerMode, myThid ) |
16 |
|
17 |
C !DESCRIPTION: |
18 |
C *==========================================================* |
19 |
C | SUBROUTINE EXCH1_UV_RX_CUBE |
20 |
C | o Forward-mode edge exchanges for RX vector on CS config. |
21 |
C *==========================================================* |
22 |
C | Controlling routine for exchange of XY edges of an array |
23 |
C | distributed in X and Y. The routine interfaces to |
24 |
C | communication routines that can use messages passing |
25 |
C | exchanges, put type exchanges or get type exchanges. |
26 |
C | This allows anything from MPI to raw memory channel to |
27 |
C | memmap segments to be used as a inter-process and/or |
28 |
C | inter-thread communiation and synchronisation |
29 |
C | mechanism. |
30 |
C | Notes -- |
31 |
C | 1. Some low-level mechanisms such as raw memory-channel |
32 |
C | or SGI/CRAY shmem put do not have direct Fortran bindings |
33 |
C | and are invoked through C stub routines. |
34 |
C | 2. Although this routine is fairly general but it does |
35 |
C | require nSx and nSy are the same for all innvocations. |
36 |
C | There are many common data structures ( myByLo, |
37 |
C | westCommunicationMode, mpiIdW etc... ) tied in with |
38 |
C | (nSx,nSy). To support arbitray nSx and nSy would require |
39 |
C | general forms of these. |
40 |
C | 3. Exchanges on the cube of vector quantities need to be |
41 |
C | paired to allow rotations and sign reversal to be applied |
42 |
C | consistently between vector components as they rotate. |
43 |
C *==========================================================* |
44 |
|
45 |
C !USES: |
46 |
IMPLICIT NONE |
47 |
|
48 |
C == Global data == |
49 |
#include "SIZE.h" |
50 |
#include "EEPARAMS.h" |
51 |
|
52 |
C !INPUT/OUTPUT PARAMETERS: |
53 |
C == Routine arguments == |
54 |
C Uarray :: (u-type) Array with edges to exchange. |
55 |
C Varray :: (v-type) Array with edges to exchange. |
56 |
C withSigns :: sign of Uarray,Varray depends on orientation |
57 |
C myOLw,myOLe :: West and East overlap region sizes. |
58 |
C myOLs,myOLn :: South and North overlap region sizes. |
59 |
C exchWidthX :: Width of data region exchanged in X. |
60 |
C exchWidthY :: Width of data region exchanged in Y. |
61 |
C Note -- |
62 |
C 1. In theory one could have a send width and |
63 |
C a receive width for each face of each tile. The only |
64 |
C restriction would be that the send width of one |
65 |
C face should equal the receive width of the sent to |
66 |
C tile face. Dont know if this would be useful. I |
67 |
C have left it out for now as it requires additional |
68 |
C bookeeping. |
69 |
C cornerMode :: Flag indicating whether corner updates are needed. |
70 |
C myThid :: my Thread Id number |
71 |
|
72 |
INTEGER myOLw, myOLe, myOLs, myOLn, myNz |
73 |
_RX Uarray( 1-myOLw:sNx+myOLe, |
74 |
& 1-myOLs:sNy+myOLn, |
75 |
& myNz, nSx, nSy ) |
76 |
_RX Varray( 1-myOLw:sNx+myOLe, |
77 |
& 1-myOLs:sNy+myOLn, |
78 |
& myNz, nSx, nSy ) |
79 |
LOGICAL withSigns |
80 |
INTEGER exchWidthX |
81 |
INTEGER exchWidthY |
82 |
INTEGER cornerMode |
83 |
INTEGER myThid |
84 |
|
85 |
C !LOCAL VARIABLES: |
86 |
C == Local variables == |
87 |
C theSimulationMode :: Holds working copy of simulation mode |
88 |
C theCornerMode :: Holds working copy of corner mode |
89 |
C I,J,K :: Loop and index counters |
90 |
C bl,bt,bn,bs,be,bw :: tile indices |
91 |
C negOne, Utmp,Vtmp :: Temps used in swapping and rotating vectors |
92 |
c INTEGER theSimulationMode |
93 |
c INTEGER theCornerMode |
94 |
INTEGER I,J,K, repeat |
95 |
INTEGER bl,bt,bn,bs,be,bw |
96 |
CHARACTER*(MAX_LEN_MBUF) msgBuf |
97 |
_RX negOne, Utmp, Vtmp |
98 |
|
99 |
C == Statement function == |
100 |
C tilemod :: Permutes indices to return neighboring tile index |
101 |
C on six face cube. |
102 |
INTEGER tilemod |
103 |
tilemod(I)=1+mod(I-1+6,6) |
104 |
CEOP |
105 |
|
106 |
c theSimulationMode = FORWARD_SIMULATION |
107 |
c theCornerMode = cornerMode |
108 |
|
109 |
c IF ( simulationMode.EQ.REVERSE_SIMULATION ) THEN |
110 |
c WRITE(msgBuf,'(A)')'EXCH1_UV_RX_CUBE: AD mode not implemented' |
111 |
c CALL PRINT_ERROR( msgBuf, myThid ) |
112 |
c STOP 'ABNORMAL END: EXCH1_UV_RX_CUBE: no AD code' |
113 |
c ENDIF |
114 |
IF ( sNx.NE.sNy .OR. |
115 |
& nSx.NE.6 .OR. nSy.NE.1 .OR. |
116 |
& nPx.NE.1 .OR. nPy.NE.1 ) THEN |
117 |
WRITE(msgBuf,'(2A)') 'EXCH1_UV_RX_CUBE: Wrong Tiling' |
118 |
CALL PRINT_ERROR( msgBuf, myThid ) |
119 |
WRITE(msgBuf,'(2A)') 'EXCH1_UV_RX_CUBE: ', |
120 |
& 'works only with sNx=sNy & nSx=6 & nSy=nPx=nPy=1' |
121 |
CALL PRINT_ERROR( msgBuf, myThid ) |
122 |
STOP 'ABNORMAL END: EXCH1_UV_RX_CUBE: Wrong Tiling' |
123 |
ENDIF |
124 |
|
125 |
negOne = 1. |
126 |
IF (withSigns) negOne = -1. |
127 |
|
128 |
C For now tile<->tile exchanges are sequentialised through |
129 |
C thread 1. This is a temporary feature for preliminary testing until |
130 |
C general tile decomposistion is in place (CNH April 11, 2001) |
131 |
CALL BAR2( myThid ) |
132 |
IF ( myThid .EQ. 1 ) THEN |
133 |
|
134 |
DO repeat=1,2 |
135 |
|
136 |
DO bl = 1, 5, 2 |
137 |
|
138 |
bt = bl |
139 |
bn=tilemod(bt+2) |
140 |
bs=tilemod(bt-1) |
141 |
be=tilemod(bt+1) |
142 |
bw=tilemod(bt-2) |
143 |
|
144 |
DO K = 1,myNz |
145 |
|
146 |
C Tile Odd:Odd+2 [get] [North<-West] |
147 |
DO J = 1,sNy+1 |
148 |
DO I = 1,exchWidthX |
149 |
Uarray(J,sNy+I,K,bt,1) = negOne*Varray(I,sNy+2-J,K,bn,1) |
150 |
ENDDO |
151 |
ENDDO |
152 |
DO J = 1,sNy |
153 |
DO I = 1,exchWidthX |
154 |
Varray(J,sNy+I,K,bt,1) = Uarray(I,sNy+1-J,K,bn,1) |
155 |
ENDDO |
156 |
ENDDO |
157 |
C Tile Odd:Odd-1 [get] [South<-North] |
158 |
DO J = 1,sNy+1 |
159 |
DO I = 1,exchWidthX |
160 |
Uarray(J,1-I,K,bt,1) = Uarray(J,sNy+1-I,K,bs,1) |
161 |
ENDDO |
162 |
ENDDO |
163 |
DO J = 1,sNy |
164 |
DO I = 1,exchWidthX |
165 |
Varray(J,1-I,K,bt,1) = Varray(J,sNy+1-I,K,bs,1) |
166 |
ENDDO |
167 |
ENDDO |
168 |
C Tile Odd:Odd+1 [get] [East<-West] |
169 |
DO J = 1,sNy |
170 |
DO I = 1,exchWidthX |
171 |
Uarray(sNx+I,J,K,bt,1) = Uarray(I,J,K,be,1) |
172 |
ENDDO |
173 |
ENDDO |
174 |
DO J = 1,sNy+1 |
175 |
DO I = 1,exchWidthX |
176 |
Varray(sNx+I,J,K,bt,1) = Varray(I,J,K,be,1) |
177 |
ENDDO |
178 |
ENDDO |
179 |
C Tile Odd:Odd-2 [get] [West<-North] |
180 |
DO J = 1,sNy |
181 |
DO I = 1,exchWidthX |
182 |
Uarray(1-I,J,K,bt,1) = Varray(sNx+1-J,sNy+1-I,K,bw,1) |
183 |
ENDDO |
184 |
ENDDO |
185 |
DO J = 1,sNy+1 |
186 |
DO I = 1,exchWidthX |
187 |
Varray(1-I,J,K,bt,1) = negOne*Uarray(sNx+2-J,sNy+1-I,K,bw,1) |
188 |
ENDDO |
189 |
ENDDO |
190 |
|
191 |
ENDDO |
192 |
|
193 |
bt = bl+1 |
194 |
bn=tilemod(bt+1) |
195 |
bs=tilemod(bt-2) |
196 |
be=tilemod(bt+2) |
197 |
bw=tilemod(bt-1) |
198 |
|
199 |
DO K = 1,myNz |
200 |
|
201 |
C Tile Even:Even+1 [get] [North<-South] |
202 |
DO J = 1,sNy+1 |
203 |
DO I = 1,exchWidthX |
204 |
Uarray(J,sNy+I,K,bt,1) = Uarray(J,I,K,bn,1) |
205 |
ENDDO |
206 |
ENDDO |
207 |
DO J = 1,sNy |
208 |
DO I = 1,exchWidthX |
209 |
Varray(J,sNy+I,K,bt,1) = Varray(J,I,K,bn,1) |
210 |
ENDDO |
211 |
ENDDO |
212 |
C Tile Even:Even-2 [get] [South<-East] |
213 |
DO J = 1,sNy+1 |
214 |
DO I = 1,exchWidthX |
215 |
Uarray(J,1-I,K,bt,1) = negOne*Varray(sNx+1-I,sNy+2-J,K,bs,1) |
216 |
ENDDO |
217 |
ENDDO |
218 |
DO J = 1,sNy |
219 |
DO I = 1,exchWidthX |
220 |
Varray(J,1-I,K,bt,1) = Uarray(sNx+1-I,sNy+1-J,K,bs,1) |
221 |
ENDDO |
222 |
ENDDO |
223 |
C Tile Even:Even+2 [get] [East<-South] |
224 |
DO J = 1,sNy |
225 |
DO I = 1,exchWidthX |
226 |
Uarray(sNx+I,J,K,bt,1) = Varray(sNx+1-J,I,K,be,1) |
227 |
ENDDO |
228 |
ENDDO |
229 |
DO J = 1,sNy+1 |
230 |
DO I = 1,exchWidthX |
231 |
Varray(sNx+I,J,K,bt,1) = negOne*Uarray(sNx+2-J,I,K,be,1) |
232 |
ENDDO |
233 |
ENDDO |
234 |
C Tile Even:Even-1 [get] [West<-East] |
235 |
DO J = 1,sNy |
236 |
DO I = 1,exchWidthX |
237 |
Uarray(1-I,J,K,bt,1) = Uarray(sNx+1-I,J,K,bw,1) |
238 |
ENDDO |
239 |
ENDDO |
240 |
DO J = 1,sNy+1 |
241 |
DO I = 1,exchWidthX |
242 |
Varray(1-I,J,K,bt,1) = Varray(sNx+1-I,J,K,bw,1) |
243 |
ENDDO |
244 |
ENDDO |
245 |
|
246 |
ENDDO |
247 |
|
248 |
ENDDO |
249 |
|
250 |
C- Add one valid uVel,vVel value next to the corner, that allows |
251 |
C to compute vorticity on a wider stencil (e.g., vort3(0,1) & (1,0)) |
252 |
DO bt = 1,6 |
253 |
DO K = 1,myNz |
254 |
C SW corner: |
255 |
Uarray(0,0,K,bt,1)=Varray(1,0,K,bt,1) |
256 |
Varray(0,0,K,bt,1)=Uarray(0,1,K,bt,1) |
257 |
C NW corner: |
258 |
Uarray(0,sNy+1,K,bt,1)= negOne*Varray(1,sNy+2,K,bt,1) |
259 |
Varray(0,sNy+2,K,bt,1)= negOne*Uarray(0,sNy,K,bt,1) |
260 |
C SE corner: |
261 |
Uarray(sNx+2,0,K,bt,1)= negOne*Varray(sNx,0,K,bt,1) |
262 |
Varray(sNx+1,0,K,bt,1)= negOne*Uarray(sNx+2,1,K,bt,1) |
263 |
C NE corner: |
264 |
Uarray(sNx+2,sNy+1,K,bt,1)=Varray(sNx,sNy+2,K,bt,1) |
265 |
Varray(sNx+1,sNy+2,K,bt,1)=Uarray(sNx+2,sNy,K,bt,1) |
266 |
ENDDO |
267 |
ENDDO |
268 |
|
269 |
C Fix degeneracy at corners |
270 |
IF (.FALSE.) THEN |
271 |
c IF (withSigns) THEN |
272 |
DO bt = 1, 6 |
273 |
DO K = 1,myNz |
274 |
C Top left |
275 |
Utmp=0.5*(Uarray(1,sNy,K,bt,1)+Uarray(0,sNy,K,bt,1)) |
276 |
Vtmp=0.5*(Varray(0,sNy+1,K,bt,1)+Varray(0,sNy,K,bt,1)) |
277 |
Varray(0,sNx+1,K,bt,1)=(Vtmp-Utmp)*0.70710678 |
278 |
Utmp=0.5*(Uarray(1,sNy+1,K,bt,1)+Uarray(2,sNy+1,K,bt,1)) |
279 |
Vtmp=0.5*(Varray(1,sNy+1,K,bt,1)+Varray(1,sNy+2,K,bt,1)) |
280 |
Uarray(1,sNy+1,K,bt,1)=(Utmp-Vtmp)*0.70710678 |
281 |
C Bottom right |
282 |
Utmp=0.5*(Uarray(sNx+1,1,K,bt,1)+Uarray(sNx+2,1,K,bt,1)) |
283 |
Vtmp=0.5*(Varray(sNx+1,1,K,bt,1)+Varray(sNx+1,2,K,bt,1)) |
284 |
Varray(sNx+1,1,K,bt,1)=(Vtmp-Utmp)*0.70710678 |
285 |
Utmp=0.5*(Uarray(sNx+1,0,K,bt,1)+Uarray(sNx,0,K,bt,1)) |
286 |
Vtmp=0.5*(Varray(sNx,1,K,bt,1)+Varray(sNx,0,K,bt,1)) |
287 |
Uarray(sNx+1,0,K,bt,1)=(Utmp-Vtmp)*0.70710678 |
288 |
C Bottom left |
289 |
Utmp=0.5*(Uarray(1,1,K,bt,1)+Uarray(0,1,K,bt,1)) |
290 |
Vtmp=0.5*(Varray(0,1,K,bt,1)+Varray(0,2,K,bt,1)) |
291 |
Varray(0,1,K,bt,1)=(Vtmp+Utmp)*0.70710678 |
292 |
Utmp=0.5*(Uarray(1,0,K,bt,1)+Uarray(2,0,K,bt,1)) |
293 |
Vtmp=0.5*(Varray(1,1,K,bt,1)+Varray(1,0,K,bt,1)) |
294 |
Uarray(1,0,K,bt,1)=(Utmp+Vtmp)*0.70710678 |
295 |
C Top right |
296 |
Utmp=0.5*(Uarray(sNx+1,sNy,K,bt,1)+Uarray(sNx+2,sNy,K,bt,1)) |
297 |
Vtmp=0.5*(Varray(sNx+1,sNy+1,K,bt,1)+Varray(sNx+1,sNy,K,bt,1)) |
298 |
Varray(sNx+1,sNy+1,K,bt,1)=(Vtmp+Utmp)*0.70710678 |
299 |
Utmp=0.5*(Uarray(sNx+1,sNy+1,K,bt,1)+Uarray(sNx,sNy+1,K,bt,1)) |
300 |
Vtmp=0.5*(Varray(sNx,sNy+1,K,bt,1)+Varray(sNx,sNy+2,K,bt,1)) |
301 |
Uarray(sNx+1,sNy+1,K,bt,1)=(Utmp+Vtmp)*0.70710678 |
302 |
ENDDO |
303 |
ENDDO |
304 |
ENDIF |
305 |
|
306 |
ENDDO |
307 |
|
308 |
ENDIF |
309 |
CALL BAR2(myThid) |
310 |
|
311 |
RETURN |
312 |
END |