/[MITgcm]/MITgcm/pkg/generic_advdiff/gad_som_adv_r.F
ViewVC logotype

Annotation of /MITgcm/pkg/generic_advdiff/gad_som_adv_r.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download)
Fri May 9 21:43:16 2008 UTC (16 years ago) by jmc
Branch: MAIN
CVS Tags: checkpoint60, checkpoint61, checkpoint59r, checkpoint61b, checkpoint61a
Changes since 1.3: +1 -4 lines
change option: GAD_ALLOW_SOM_ADVECT to GAD_ALLOW_TS_SOM_ADV which only
applies to files where Temperature & salinity 2nd Order moments are used

1 jmc 1.4 C $Header: /u/gcmpack/MITgcm/pkg/generic_advdiff/gad_som_adv_r.F,v 1.3 2008/01/08 19:57:34 jmc Exp $
2 jmc 1.1 C $Name: $
3    
4     #include "GAD_OPTIONS.h"
5    
6     CBOP
7     C !ROUTINE: GAD_SOM_ADV_R
8    
9     C !INTERFACE: ==========================================================
10     SUBROUTINE GAD_SOM_ADV_R(
11     I bi,bj,k, kUp, kDw,
12     I deltaTloc, rTrans, maskUp,
13     U sm_v, sm_o, sm_x, sm_y, sm_z,
14     U sm_xx, sm_yy, sm_zz, sm_xy, sm_xz, sm_yz,
15     U alp, aln, fp_v, fn_v, fp_o, fn_o,
16     U fp_x, fn_x, fp_y, fn_y, fp_z, fn_z,
17     U fp_xx, fn_xx, fp_yy, fn_yy, fp_zz, fn_zz,
18     U fp_xy, fn_xy, fp_xz, fn_xz, fp_yz, fn_yz,
19     O wT,
20     I myThid )
21    
22     C !DESCRIPTION:
23     C Calculates the area integrated vertical flux due to advection
24     C of a tracer using
25     C--
26     C Second-Order Moments Advection of tracer in Z-direction
27     C ref: M.J.Prather, 1986, JGR, 91, D6, pp 6671-6681.
28     C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
29     C The 3-D grid has dimension (Nx,Ny,Nz) with corresponding
30     C velocity field (U,V,W). Parallel subroutine calculate
31     C advection in the X- and Y- directions.
32     C The moment [Si] are as defined in the text, Sm refers to
33     C the total mass in each grid box
34     C the moments [Fi] are similarly defined and used as temporary
35     C storage for portions of the grid boxes in transit.
36     C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
37    
38     C !USES: ===============================================================
39     IMPLICIT NONE
40     #include "SIZE.h"
41     #include "EEPARAMS.h"
42     #include "PARAMS.h"
43     #include "SURFACE.h"
44     c #include "GRID.h"
45     #include "GAD.h"
46    
47     C !INPUT PARAMETERS: ===================================================
48     C bi,bj :: tile indices
49     C k :: vertical level
50     C kUp :: index into 2 1/2D array, toggles between 1 and 2
51     C kDw :: index into 2 1/2D array, toggles between 2 and 1
52     C rTrans :: vertical volume transport
53     C maskUp :: 2-D array mask for W points
54     C myThid :: my Thread Id. number
55     INTEGER bi,bj,k, kUp, kDw
56     _RL deltaTloc
57     _RL rTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
58     _RS maskUp(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
59     c _RL tracer(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
60     INTEGER myThid
61    
62     C !OUTPUT PARAMETERS: ==================================================
63     C sm_v :: volume of grid cell
64     C sm_o :: tracer content of grid cell (zero order moment)
65     C sm_x,y,z :: 1rst order moment of tracer distribution, in x,y,z direction
66     C sm_xx,yy,zz :: 2nd order moment of tracer distribution, in x,y,z direction
67     C sm_xy,xz,yz :: 2nd order moment of tracer distr., in cross direction xy,xz,yz
68     C wT :: vertical advective flux
69     _RL sm_v (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
70     _RL sm_o (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
71     _RL sm_x (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
72     _RL sm_y (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
73     _RL sm_z (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
74     _RL sm_xx (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
75     _RL sm_yy (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
76     _RL sm_zz (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
77     _RL sm_xy (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
78     _RL sm_xz (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
79     _RL sm_yz (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
80     _RL alp (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
81     _RL aln (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
82     _RL fp_v (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
83     _RL fn_v (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
84     _RL fp_o (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
85     _RL fn_o (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
86     _RL fp_x (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
87     _RL fn_x (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
88     _RL fp_y (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
89     _RL fn_y (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
90     _RL fp_z (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
91     _RL fn_z (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
92     _RL fp_xx(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
93     _RL fn_xx(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
94     _RL fp_yy(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
95     _RL fn_yy(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
96     _RL fp_zz(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
97     _RL fn_zz(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
98     _RL fp_xy(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
99     _RL fn_xy(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
100     _RL fp_xz(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
101     _RL fn_xz(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
102     _RL fp_yz(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
103     _RL fn_yz(1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
104     _RL wT (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
105    
106     C !LOCAL VARIABLES: ====================================================
107     C i,j :: loop indices
108     C wLoc :: volume transported (per time step)
109     _RL two, three
110     PARAMETER( two = 2. _d 0 )
111     PARAMETER( three = 3. _d 0 )
112     INTEGER i,j
113     INTEGER km1
114 jmc 1.3 _RL recip_dT
115 jmc 1.1 _RL wLoc, alf1, alf1q, alpmn
116     _RL alfp, alpq, alp1, locTp
117     _RL alfn, alnq, aln1, locTn
118     CEOP
119    
120 jmc 1.3 recip_dT = 0.
121     IF ( deltaTloc.GT.0. _d 0 ) recip_dT = 1.0 _d 0 / deltaTloc
122    
123 jmc 1.1 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
124     C--- part.1 : calculate flux for all moments
125 jmc 1.2 DO j=jMinAdvR,jMaxAdvR
126     DO i=iMinAdvR,iMaxAdvR
127 jmc 1.1 wLoc = rTrans(i,j)*deltaTloc
128     C-- Flux from (k) to (k-1) when W>0 (i.e., take upper side of box k)
129     C- note: Linear free surface case: this takes care of w_surf advection out
130     C of the domain since for this particular case, rTrans is not masked
131     fp_v (i,j,kUp) = MAX( 0. _d 0, wLoc )
132     alp (i,j,kUp) = fp_v(i,j,kUp)/sm_v(i,j,k)
133     alpq = alp(i,j,kUp)*alp(i,j,kUp)
134     alp1 = 1. _d 0 - alp(i,j,kUp)
135     C- Create temporary moments/masses for partial boxes in transit
136     C use same indexing as velocity, "p" for positive W
137     fp_o (i,j,kUp) = alp(i,j,kUp)*
138     & ( sm_o(i,j, k ) + alp1*sm_z(i,j, k )
139     & + alp1*(alp1-alp(i,j,kUp))*sm_zz(i,j, k )
140     & )
141     fp_z (i,j,kUp) = alpq*
142     & ( sm_z(i,j, k ) + three*alp1*sm_zz(i,j, k ) )
143     fp_zz(i,j,kUp) = alp(i,j,kUp)*alpq*sm_zz(i,j, k )
144     fp_x (i,j,kUp) = alp(i,j,kUp)*
145     & ( sm_x(i,j, k ) + alp1*sm_xz(i,j, k ) )
146     fp_y (i,j,kUp) = alp(i,j,kUp)*
147     & ( sm_y(i,j, k ) + alp1*sm_yz(i,j, k ) )
148     fp_xz(i,j,kUp) = alpq *sm_xz(i,j, k )
149     fp_yz(i,j,kUp) = alpq *sm_yz(i,j, k )
150     fp_xx(i,j,kUp) = alp(i,j,kUp)*sm_xx(i,j, k )
151     fp_yy(i,j,kUp) = alp(i,j,kUp)*sm_yy(i,j, k )
152     fp_xy(i,j,kUp) = alp(i,j,kUp)*sm_xy(i,j, k )
153     ENDDO
154     ENDDO
155     IF ( k.EQ.1 ) THEN
156     C-- Linear free surface, calculate w_surf (<0) advection term
157     km1 = 1
158 jmc 1.2 DO j=jMinAdvR,jMaxAdvR
159     DO i=iMinAdvR,iMaxAdvR
160 jmc 1.1 wLoc = rTrans(i,j)*deltaTloc
161     C- Flux from above to (k) when W<0 , surface case:
162     C take box k=1, assuming zero 1rst & 2nd moment in Z dir.
163     fn_v (i,j,kUp) = MAX( 0. _d 0, -wLoc )
164     aln (i,j,kUp) = fn_v(i,j,kUp)/sm_v(i,j,km1)
165     alnq = aln(i,j,kUp)*aln(i,j,kUp)
166     aln1 = 1. _d 0 - aln(i,j,kUp)
167     C- Create temporary moments/masses for partial boxes in transit
168     C use same indexing as velocity, "n" for negative W
169     fn_o (i,j,kUp) = aln(i,j,kUp)*sm_o(i,j,km1)
170     fn_z (i,j,kUp) = 0. _d 0
171     fn_zz(i,j,kUp) = 0. _d 0
172     fn_x (i,j,kUp) = aln(i,j,kUp)*sm_x(i,j,km1)
173     fn_y (i,j,kUp) = aln(i,j,kUp)*sm_y(i,j,km1)
174     fn_xz(i,j,kUp) = 0. _d 0
175     fn_yz(i,j,kUp) = 0. _d 0
176     fn_xx(i,j,kUp) = aln(i,j,kUp)*sm_xx(i,j,km1)
177     fn_yy(i,j,kUp) = aln(i,j,kUp)*sm_yy(i,j,km1)
178     fn_xy(i,j,kUp) = aln(i,j,kUp)*sm_xy(i,j,km1)
179     C-- Save zero-order flux:
180 jmc 1.3 wT(i,j) = ( fp_o(i,j,kUp) - fn_o(i,j,kUp) )*recip_dT
181 jmc 1.1 ENDDO
182     ENDDO
183     ELSE
184     C-- Interior only: mask rTrans (if not already done)
185     km1 = k-1
186 jmc 1.2 DO j=jMinAdvR,jMaxAdvR
187     DO i=iMinAdvR,iMaxAdvR
188 jmc 1.1 wLoc = maskUp(i,j)*rTrans(i,j)*deltaTloc
189     C- Flux from (k-1) to (k) when W<0 (i.e., take lower side of box k-1)
190     fn_v (i,j,kUp) = MAX( 0. _d 0, -wLoc )
191     aln (i,j,kUp) = fn_v(i,j,kUp)/sm_v(i,j,km1)
192     alnq = aln(i,j,kUp)*aln(i,j,kUp)
193     aln1 = 1. _d 0 - aln(i,j,kUp)
194     C- Create temporary moments/masses for partial boxes in transit
195     C use same indexing as velocity, "n" for negative W
196     fn_o (i,j,kUp) = aln(i,j,kUp)*
197     & ( sm_o(i,j,km1) - aln1*sm_z(i,j,km1)
198     & + aln1*(aln1-aln(i,j,kUp))*sm_zz(i,j,km1)
199     & )
200     fn_z (i,j,kUp) = alnq*
201     & ( sm_z(i,j,km1) - three*aln1*sm_zz(i,j,km1) )
202     fn_zz(i,j,kUp) = aln(i,j,kUp)*alnq*sm_zz(i,j,km1)
203     fn_x (i,j,kUp) = aln(i,j,kUp)*
204     & ( sm_x(i,j,km1) - aln1*sm_xz(i,j,km1) )
205     fn_y (i,j,kUp) = aln(i,j,kUp)*
206     & ( sm_y(i,j,km1) - aln1*sm_yz(i,j,km1) )
207     fn_xz(i,j,kUp) = alnq *sm_xz(i,j,km1)
208     fn_yz(i,j,kUp) = alnq *sm_yz(i,j,km1)
209     fn_xx(i,j,kUp) = aln(i,j,kUp)*sm_xx(i,j,km1)
210     fn_yy(i,j,kUp) = aln(i,j,kUp)*sm_yy(i,j,km1)
211     fn_xy(i,j,kUp) = aln(i,j,kUp)*sm_xy(i,j,km1)
212     C-- Save zero-order flux:
213 jmc 1.3 wT(i,j) = ( fp_o(i,j,kUp) - fn_o(i,j,kUp) )*recip_dT
214 jmc 1.1 ENDDO
215     ENDDO
216     C-- end surface/interior cases for W<0 advective fluxes
217     ENDIF
218     IF ( usingPCoords .AND. k.NE.1 .AND.
219     & .NOT.rigidLid .AND. nonlinFreeSurf.LE.0 ) THEN
220     C-- Linear free surface, but surface not @ k=1 :
221     C calculate w_surf (<0) advection term from current level
222     C moments assuming zero 1rst & 2nd moment in Z dir. ;
223     C and add to previous fluxes; note: identical to resetting fluxes
224     C since previous fluxes are zero in this case (=> let TAF decide)
225     km1 = k
226 jmc 1.2 DO j=jMinAdvR,jMaxAdvR
227     DO i=iMinAdvR,iMaxAdvR
228 jmc 1.1 wLoc = rTrans(i,j)*deltaTloc
229     IF ( k.EQ.ksurfC(i,j,bi,bj) ) THEN
230     C- Flux from (k-1) to (k) when W<0 (special surface case, take box k)
231     fn_v (i,j,kUp) = MAX( 0. _d 0, -wLoc )
232     aln (i,j,kUp) = fn_v(i,j,kUp)/sm_v(i,j,km1)
233     C- Create temporary moments/masses for partial boxes in transit
234     C use same indexing as velocity, "n" for negative W
235     fn_o (i,j,kUp) = aln(i,j,kUp)*sm_o(i,j,km1)
236     fn_x (i,j,kUp) = aln(i,j,kUp)*sm_x(i,j,km1)
237     fn_y (i,j,kUp) = aln(i,j,kUp)*sm_y(i,j,km1)
238     fn_xx(i,j,kUp) = aln(i,j,kUp)*sm_xx(i,j,km1)
239     fn_yy(i,j,kUp) = aln(i,j,kUp)*sm_yy(i,j,km1)
240     fn_xy(i,j,kUp) = aln(i,j,kUp)*sm_xy(i,j,km1)
241     C-- Save zero-order flux:
242 jmc 1.3 wT(i,j) = ( fp_o(i,j,kUp) - fn_o(i,j,kUp) )*recip_dT
243 jmc 1.1 ENDIF
244     ENDDO
245     ENDDO
246     ENDIF
247    
248     C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
249     C--- part.2 : re-adjust moments remaining in the box
250     C take off from grid box (k): negative W(kDw) and positive W(kUp)
251 jmc 1.2 DO j=jMinAdvR,jMaxAdvR
252     DO i=iMinAdvR,iMaxAdvR
253 jmc 1.1 alf1 = 1. _d 0 - aln(i,j,kDw) - alp(i,j,kUp)
254     alf1q = alf1*alf1
255     alpmn = alp(i,j,kUp) - aln(i,j,kDw)
256     sm_v (i,j,k) = sm_v (i,j,k) - fn_v (i,j,kDw) - fp_v (i,j,kUp)
257     sm_o (i,j,k) = sm_o (i,j,k) - fn_o (i,j,kDw) - fp_o (i,j,kUp)
258     sm_z (i,j,k) = alf1q*( sm_z(i,j,k) - three*alpmn*sm_zz(i,j,k) )
259     sm_zz(i,j,k) = alf1*alf1q*sm_zz(i,j,k)
260     sm_xz(i,j,k) = alf1q*sm_xz(i,j,k)
261     sm_yz(i,j,k) = alf1q*sm_yz(i,j,k)
262     sm_x (i,j,k) = sm_x (i,j,k) - fn_x (i,j,kDw) - fp_x (i,j,kUp)
263     sm_xx(i,j,k) = sm_xx(i,j,k) - fn_xx(i,j,kDw) - fp_xx(i,j,kUp)
264     sm_y (i,j,k) = sm_y (i,j,k) - fn_y (i,j,kDw) - fp_y (i,j,kUp)
265     sm_yy(i,j,k) = sm_yy(i,j,k) - fn_yy(i,j,kDw) - fp_yy(i,j,kUp)
266     sm_xy(i,j,k) = sm_xy(i,j,k) - fn_xy(i,j,kDw) - fp_xy(i,j,kUp)
267     ENDDO
268     ENDDO
269    
270     C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
271     C--- part.3 : Put the temporary moments into appropriate neighboring boxes
272     C add into grid box (k): positive W(kDw) and negative W(kUp)
273 jmc 1.2 DO j=jMinAdvR,jMaxAdvR
274     DO i=iMinAdvR,iMaxAdvR
275 jmc 1.1 sm_v (i,j,k) = sm_v (i,j,k) + fp_v (i,j,kDw) + fn_v (i,j,kUp)
276     alfp = fp_v(i,j,kDw)/sm_v(i,j,k)
277     alfn = fn_v(i,j,kUp)/sm_v(i,j,k)
278     alf1 = 1. _d 0 - alfp - alfn
279     alp1 = 1. _d 0 - alfp
280     aln1 = 1. _d 0 - alfn
281     alpmn = alfp - alfn
282     locTp = alfp*sm_o(i,j,k) - alp1*fp_o(i,j,kDw)
283     locTn = alfn*sm_o(i,j,k) - aln1*fn_o(i,j,kUp)
284     sm_zz(i,j,k) = alf1*alf1*sm_zz(i,j,k) + alfp*alfp*fp_zz(i,j,kDw)
285     & + alfn*alfn*fn_zz(i,j,kUp)
286     & - 5. _d 0*(-alpmn*alf1*sm_z(i,j,k) + alfp*alp1*fp_z(i,j,kDw)
287     & - alfn*aln1*fn_z(i,j,kUp)
288     & + two*alfp*alfn*sm_o(i,j,k) + (alp1-alfp)*locTp
289     & + (aln1-alfn)*locTn
290     & )
291     sm_xz(i,j,k) = alf1*sm_xz(i,j,k) + alfp*fp_xz(i,j,kDw)
292     & + alfn*fn_xz(i,j,kUp)
293     & + three*( alpmn*sm_x(i,j,k) - alp1*fp_x(i,j,kDw)
294     & + aln1*fn_x(i,j,kUp)
295     & )
296     sm_yz(i,j,k) = alf1*sm_yz(i,j,k) + alfp*fp_yz(i,j,kDw)
297     & + alfn*fn_yz(i,j,kUp)
298     & + three*( alpmn*sm_y(i,j,k) - alp1*fp_y(i,j,kDw)
299     & + aln1*fn_y(i,j,kUp)
300     & )
301     sm_z (i,j,k) = alf1*sm_z(i,j,k) + alfp*fp_z(i,j,kDw)
302     & + alfn*fn_z(i,j,kUp)
303     & + three*( locTp - locTn )
304     sm_o (i,j,k) = sm_o (i,j,k) + fp_o (i,j,kDw) + fn_o (i,j,kUp)
305     sm_x (i,j,k) = sm_x (i,j,k) + fp_x (i,j,kDw) + fn_x (i,j,kUp)
306     sm_xx(i,j,k) = sm_xx(i,j,k) + fp_xx(i,j,kDw) + fn_xx(i,j,kUp)
307     sm_y (i,j,k) = sm_y (i,j,k) + fp_y (i,j,kDw) + fn_y (i,j,kUp)
308     sm_yy(i,j,k) = sm_yy(i,j,k) + fp_yy(i,j,kDw) + fn_yy(i,j,kUp)
309     sm_xy(i,j,k) = sm_xy(i,j,k) + fp_xy(i,j,kDw) + fn_xy(i,j,kUp)
310     ENDDO
311     ENDDO
312    
313     RETURN
314     END

  ViewVC Help
Powered by ViewVC 1.1.22