/[MITgcm]/MITgcm/pkg/thsice/thsice_advdiff.F
ViewVC logotype

Contents of /MITgcm/pkg/thsice/thsice_advdiff.F

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


Revision 1.4 - (show annotations) (download)
Mon Apr 9 15:51:22 2007 UTC (17 years, 1 month ago) by jmc
Branch: MAIN
CVS Tags: checkpoint58y_post
Changes since 1.3: +30 -31 lines
re-write sea-ice state adjusment in 2 steps, to avoid truncation problems.

1 C $Header: /u/gcmpack/MITgcm/pkg/thsice/thsice_advdiff.F,v 1.3 2007/04/08 18:53:16 jmc Exp $
2 C $Name: $
3
4 #include "THSICE_OPTIONS.h"
5 #ifdef ALLOW_GENERIC_ADVDIFF
6 # include "GAD_OPTIONS.h"
7 #endif
8
9 CBOP
10 C !ROUTINE: THSICE_ADVDIFF
11
12 C !INTERFACE: ==========================================================
13 SUBROUTINE THSICE_ADVDIFF(
14 U uIce, vIce,
15 I bi, bj, myTime, myIter, myThid )
16
17 C !DESCRIPTION: \bv
18 C *===========================================================*
19 C | SUBROUTINE THSICE_ADVDIFF
20 C | o driver for different advection routines
21 C | calls an adaption of gad_advection to call different
22 C | advection routines of pkg/generic_advdiff
23 C *===========================================================*
24 C \ev
25
26 C !USES: ===============================================================
27 IMPLICIT NONE
28
29 C === Global variables ===
30 C oceFWfx :: fresh water flux to the ocean [kg/m^2/s]
31 C oceSflx :: salt flux to the ocean [psu.kg/m^2/s] (~g/m^2/s)
32 C oceQnet :: heat flux to the ocean [W/m^2]
33
34 #include "SIZE.h"
35 #include "EEPARAMS.h"
36 #include "PARAMS.h"
37 #include "GRID.h"
38 #include "THSICE_SIZE.h"
39 #include "THSICE_PARAMS.h"
40 #include "THSICE_VARS.h"
41 #include "THSICE_2DYN.h"
42 #ifdef ALLOW_GENERIC_ADVDIFF
43 # include "GAD.h"
44 #endif
45
46 C !INPUT PARAMETERS: ===================================================
47 C === Routine arguments ===
48 C uIce/vIce :: ice velocity on C-grid [m/s]
49 C bi,bj :: Tile indices
50 C myTime :: Current time in simulation (s)
51 C myIter :: Current iteration number
52 C myThid :: My Thread Id. number
53 _RL uIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
54 _RL vIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
55 INTEGER bi,bj
56 _RL myTime
57 INTEGER myIter
58 INTEGER myThid
59 CEndOfInterface
60
61 #ifdef ALLOW_THSICE
62 C !LOCAL VARIABLES: ====================================================
63 C === Local variables ===
64 C i,j, :: Loop counters
65 C uTrans :: sea-ice area transport, x direction
66 C vTrans :: sea-ice area transport, y direction
67 C uTrIce :: sea-ice volume transport, x direction
68 C vTrIce :: sea-ice volume transport, y direction
69 C afx :: horizontal advective flux, x direction
70 C afy :: horizontal advective flux, y direction
71 C iceFrc :: (new) sea-ice fraction
72 C iceVol :: temporary array used in advection S/R
73 C oldVol :: (old) sea-ice volume
74 C msgBuf :: Informational/error meesage buffer
75 INTEGER i, j
76 LOGICAL thSIce_multiDimAdv
77 CHARACTER*(MAX_LEN_MBUF) msgBuf
78
79 _RL uTrans (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
80 _RL vTrans (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
81 _RL uTrIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
82 _RL vTrIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
83 _RL afx (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
84 _RL afy (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
85 _RS maskOce (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
86 _RL iceFrc (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
87 _RL iceVol (1-Olx:sNx+Olx,1-Oly:sNy+Oly)
88 _RL oldVol (1-Olx:sNx+Olx,1-Oly:sNy+Oly)
89 _RL r_minArea
90 _RL meanCellArea, areaEpsil, vol_Epsil
91 #ifdef ALLOW_DIAGNOSTICS
92 CHARACTER*8 diagName
93 CHARACTER*4 THSICE_DIAG_SUFX, diagSufx
94 EXTERNAL THSICE_DIAG_SUFX
95 #endif
96 #ifdef ALLOW_DBUG_THSICE
97 _RL tmpVar, sumVar1, sumVar2
98 #endif
99 LOGICAL dBugFlag
100 #include "THSICE_DEBUG.h"
101 CEOP
102
103 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
104 C areaEpsil, vol_Epsil are 2 small numbers for ice area & ice volume:
105 C if ice area (=ice fraction * grid-cell area) or ice volume (= effective
106 C thickness * grid-cell area) are too small (i.e.: < areaEpsil,vol_Epsil)
107 C will assume that ice is gone, and will loose mass or energy.
108 C However, if areaEpsil,vol_Epsil are much smaller than minimun ice area
109 C (iceMaskMin*rAc) and minimum ice volume (iceMaskMin*himin*rAc),
110 C good chance that this will never happen within 1 time step.
111
112 dBugFlag = debugLevel.GE.debLevB
113
114 C- definitively not an accurate computation of mean grid-cell area;
115 C but what matter here is just to have the right order of magnitude.
116 meanCellArea = Nx*Ny
117 meanCellArea = globalArea / meanCellArea
118 areaEpsil = 1. _d -10 * meanCellArea
119 vol_Epsil = 1. _d -15 * meanCellArea
120
121 r_minArea = 0. _d 0
122 IF ( iceMaskMin.GT.0. _d 0 ) r_minArea = 1. _d 0 / iceMaskMin
123
124 thSIce_multiDimAdv = .TRUE.
125 #ifdef ALLOW_GENERIC_ADVDIFF
126 IF ( thSIceAdvScheme.EQ.ENUM_CENTERED_2ND
127 & .OR.thSIceAdvScheme.EQ.ENUM_UPWIND_3RD
128 & .OR.thSIceAdvScheme.EQ.ENUM_CENTERED_4TH ) THEN
129 thSIce_multiDimAdv = .FALSE.
130 ENDIF
131 #endif /* ALLOW_GENERIC_ADVDIFF */
132
133 C-- Initialisation (+ build oceanic mask)
134 DO j=1-OLy,sNy+OLy
135 DO i=1-OLx,sNx+OLx
136 maskOce(i,j) = 0. _d 0
137 IF ( hOceMxL(i,j,bi,bj).GT.0. ) maskOce(i,j) = 1.
138 iceVol(i,j) = 0. _d 0
139 uTrans(i,j) = 0. _d 0
140 vTrans(i,j) = 0. _d 0
141 uTrIce(i,j) = 0. _d 0
142 vTrIce(i,j) = 0. _d 0
143 oceFWfx(i,j,bi,bj) = 0. _d 0
144 oceSflx(i,j,bi,bj) = 0. _d 0
145 oceQnet(i,j,bi,bj) = 0. _d 0
146 ENDDO
147 ENDDO
148
149 IF ( thSIce_diffK .GT. 0. ) THEN
150 CALL THSICE_DIFFUSION(
151 I maskOce,
152 U uIce, vIce,
153 I bi, bj, myTime, myIter, myThid )
154 ENDIF
155
156 IF ( thSIce_multiDimAdv ) THEN
157
158 C- Calculate ice transports through tracer cell faces.
159 DO j=1-Oly,sNy+Oly
160 DO i=1-Olx+1,sNx+Olx
161 uTrIce(i,j) = uIce(i,j)*_dyG(i,j,bi,bj)
162 & *maskOce(i-1,j)*maskOce(i,j)
163 ENDDO
164 ENDDO
165 DO j=1-Oly+1,sNy+Oly
166 DO i=1-Olx,sNx+Olx
167 vTrIce(i,j) = vIce(i,j)*_dxG(i,j,bi,bj)
168 & *maskOce(i,j-1)*maskOce(i,j)
169 ENDDO
170 ENDDO
171
172 C-- Fractional area
173 DO j=1-Oly,sNy+Oly
174 DO i=1-Olx,sNx+Olx
175 iceFrc(i,j) = iceMask(i,j,bi,bj)
176 ENDDO
177 ENDDO
178 CALL THSICE_ADVECTION(
179 I GAD_SI_FRAC, thSIceAdvScheme, .TRUE.,
180 I uTrIce, vTrIce, maskOce, thSIce_deltaT, areaEpsil,
181 U iceVol, iceFrc,
182 O uTrans, vTrans,
183 I bi, bj, myTime, myIter, myThid )
184
185 C-- Snow thickness
186 DO j=1-Oly,sNy+Oly
187 DO i=1-Olx,sNx+Olx
188 iceVol(i,j) = iceMask(i,j,bi,bj)*rA(i,j,bi,bj)
189 ENDDO
190 ENDDO
191 CALL THSICE_ADVECTION(
192 I GAD_SI_HSNOW, thSIceAdvScheme, .FALSE.,
193 I uTrans, vTrans, maskOce, thSIce_deltaT, areaEpsil,
194 U iceVol, snowHeight(1-Olx,1-Oly,bi,bj),
195 O afx, afy,
196 I bi, bj, myTime, myIter, myThid )
197
198 C-- sea-ice Thickness
199 DO j=1-Oly,sNy+Oly
200 DO i=1-Olx,sNx+Olx
201 iceVol(i,j) = iceMask(i,j,bi,bj)*rA(i,j,bi,bj)
202 oldVol(i,j) = iceVol(i,j)*iceHeight(i,j,bi,bj)
203 ENDDO
204 ENDDO
205 CALL THSICE_ADVECTION(
206 I GAD_SI_HICE, thSIceAdvScheme, .FALSE.,
207 I uTrans, vTrans, maskOce, thSIce_deltaT, areaEpsil,
208 U iceVol, iceHeight(1-Olx,1-Oly,bi,bj),
209 O uTrIce, vTrIce,
210 I bi, bj, myTime, myIter, myThid )
211 #ifdef ALLOW_DBUG_THSICE
212 IF ( dBugFlag ) THEN
213 sumVar1 = 0.
214 sumVar2 = 0.
215 DO j=1,sNy
216 DO i=1,sNx
217 C- Check that updated iceVol = iceFrc*rA
218 tmpVar = ABS(iceVol(i,j)-iceFrc(i,j)*rA(i,j,bi,bj))
219 IF ( tmpVar.GT.0. ) THEN
220 sumVar1 = sumVar1 + 1.
221 sumVar2 = sumVar2 + tmpVar
222 ENDIF
223 IF ( tmpVar.GT.vol_Epsil ) THEN
224 WRITE(6,'(A,2I4,2I2,I12)') 'ARE_ADV: ij,bij,it=',
225 & i,j,bi,bj,myIter
226 WRITE(6,'(2(A,1P2E14.6))') 'ARE_ADV: iceVol,iceFrc*rA=',
227 & iceVol(i,j),iceFrc(i,j)*rA(i,j,bi,bj),
228 & ' , diff=', tmpVar
229 ENDIF
230 IF ( dBug(i,j,bi,bj) ) THEN
231 WRITE(6,'(A,2I4,2I2,I12)') 'ICE_ADV: ij,bij,it=',
232 & i,j,bi,bj,myIter
233 WRITE(6,'(2(A,1P2E14.6))')
234 & 'ICE_ADV: uIce=', uIce(i,j), uIce(i+1,j),
235 & ' , vIce=', vIce(i,j), vIce(i,j+1)
236 WRITE(6,'(2(A,1P2E14.6))')
237 c & 'ICE_ADV: heff_b,a=', HEFF(i,j,2,bi,bj),HEFF(i,j,1,bi,bj)
238 c WRITE(6,'(A,1P4E14.6)') 'ICE_ADV: mFx=', gFld(i,j)
239 ENDIF
240 ENDDO
241 ENDDO
242 IF ( sumVar2.GT.vol_Epsil )
243 & WRITE(6,'(A,2I2,I10,A,I4,1P2E14.6)') 'ARE_ADV: bij,it:',
244 & bi,bj,myIter, ' ; Npts,aveDiff,Epsil=',
245 & INT(sumVar1),sumVar2/sumVar1,vol_Epsil
246 ENDIF
247 #endif
248 #ifdef ALLOW_DIAGNOSTICS
249 C-- Diagnosse advective fluxes (ice-fraction, snow & ice thickness):
250 IF ( useDiagnostics ) THEN
251 diagSufx = THSICE_DIAG_SUFX( GAD_SI_FRAC, myThid )
252 diagName = 'ADVx'//diagSufx
253 CALL DIAGNOSTICS_FILL( uTrans, diagName, 1,1,2,bi,bj, myThid )
254 diagName = 'ADVy'//diagSufx
255 CALL DIAGNOSTICS_FILL( vTrans, diagName, 1,1,2,bi,bj, myThid )
256
257 diagSufx = THSICE_DIAG_SUFX( GAD_SI_HSNOW, myThid )
258 diagName = 'ADVx'//diagSufx
259 CALL DIAGNOSTICS_FILL( afx, diagName, 1,1,2,bi,bj, myThid )
260 diagName = 'ADVy'//diagSufx
261 CALL DIAGNOSTICS_FILL( afy, diagName, 1,1,2,bi,bj, myThid )
262
263 diagSufx = THSICE_DIAG_SUFX( GAD_SI_HICE, myThid )
264 diagName = 'ADVx'//diagSufx
265 CALL DIAGNOSTICS_FILL( uTrIce, diagName, 1,1,2,bi,bj, myThid )
266 diagName = 'ADVy'//diagSufx
267 CALL DIAGNOSTICS_FILL( vTrIce, diagName, 1,1,2,bi,bj, myThid )
268 ENDIF
269 #endif
270
271 C-- Enthalpy in layer 1
272 DO j=1-Oly,sNy+Oly
273 DO i=1-Olx,sNx+Olx
274 iceVol(i,j) = oldVol(i,j)
275 ENDDO
276 ENDDO
277 CALL THSICE_ADVECTION(
278 I GAD_SI_QICE1, thSIceAdvScheme, .FALSE.,
279 I uTrIce, vTrIce, maskOce, thSIce_deltaT, vol_Epsil,
280 U iceVol, Qice1(1-Olx,1-Oly,bi,bj),
281 O afx, afy,
282 I bi, bj, myTime, myIter, myThid )
283 #ifdef ALLOW_DBUG_THSICE
284 IF ( dBugFlag ) THEN
285 DO j=1,sNy
286 DO i=1,sNx
287 IF ( dBug(i,j,bi,bj) ) THEN
288 c WRITE(6,'(A,1P4E14.6)') 'ICE_ADV: Qice1_b,a=',
289 c & Qice1(i,j,bi,bj),
290 c & ( iceFld(i,j) + thSIce_deltaT * gFld(i,j)
291 c & ) * recip_heff(i,j)
292 c WRITE(6,'(A,1P4E14.6)') 'ICE_ADV: q1Fx=', gFld(i,j)
293 ENDIF
294 ENDDO
295 ENDDO
296 ENDIF
297 #endif
298 #ifdef ALLOW_DIAGNOSTICS
299 IF ( useDiagnostics ) THEN
300 diagSufx = THSICE_DIAG_SUFX( GAD_SI_QICE1, myThid )
301 diagName = 'ADVx'//diagSufx
302 CALL DIAGNOSTICS_FILL( afx, diagName, 1,1,2,bi,bj, myThid )
303 diagName = 'ADVy'//diagSufx
304 CALL DIAGNOSTICS_FILL( afy, diagName, 1,1,2,bi,bj, myThid )
305 ENDIF
306 #endif
307
308 C-- Enthalpy in layer 2
309 DO j=1-Oly,sNy+Oly
310 DO i=1-Olx,sNx+Olx
311 iceVol(i,j) = oldVol(i,j)
312 ENDDO
313 ENDDO
314 CALL THSICE_ADVECTION(
315 I GAD_SI_QICE2, thSIceAdvScheme, .FALSE.,
316 I uTrIce, vTrIce, maskOce, thSIce_deltaT, vol_Epsil,
317 U iceVol, Qice2(1-Olx,1-Oly,bi,bj),
318 O afx, afy,
319 I bi, bj, myTime, myIter, myThid )
320 #ifdef ALLOW_DBUG_THSICE
321 IF ( dBugFlag ) THEN
322 sumVar1 = 0.
323 sumVar2 = 0.
324 DO j=1,sNy
325 DO i=1,sNx
326 C- Check that updated iceVol = Hic*Frc*rA
327 tmpVar = ABS(iceVol(i,j)
328 & -iceHeight(i,j,bi,bj)*iceFrc(i,j)*rA(i,j,bi,bj))
329 IF ( tmpVar.GT.0. ) THEN
330 sumVar1 = sumVar1 + 1.
331 sumVar2 = sumVar2 + tmpVar
332 ENDIF
333 IF ( tmpVar.GT.vol_Epsil ) THEN
334 WRITE(6,'(A,2I4,2I2,I12)') 'VOL_ADV: ij,bij,it=',
335 & i,j,bi,bj,myIter
336 WRITE(6,'(2(A,1P2E14.6))') 'VOL_ADV: iceVol,Hic*Frc*rA=',
337 & iceVol(i,j),iceHeight(i,j,bi,bj)*iceFrc(i,j)*rA(i,j,bi,bj),
338 & ' , diff=', tmpVar
339 ENDIF
340 IF ( dBug(i,j,bi,bj) ) THEN
341 c WRITE(6,'(A,1P4E14.6)') 'ICE_ADV: Qice2_b,a=',
342 c & Qice2(i,j,bi,bj),
343 c & ( iceFld(i,j) + thSIce_deltaT * gFld(i,j)
344 c & ) * recip_heff(i,j)
345 c WRITE(6,'(A,1P4E14.6)') 'ICE_ADV: q2Fx=', gFld(i,j)
346 ENDIF
347 ENDDO
348 ENDDO
349 IF ( sumVar2.GT.vol_Epsil )
350 & WRITE(6,'(A,2I2,I10,A,I4,1P2E14.6)') 'VOL_ADV: bij,it:',
351 & bi,bj,myIter, ' ; Npts,aveDiff,Epsil=',
352 & INT(sumVar1),sumVar2/sumVar1,vol_Epsil
353 ENDIF
354 #endif
355 #ifdef ALLOW_DIAGNOSTICS
356 IF ( useDiagnostics ) THEN
357 diagSufx = THSICE_DIAG_SUFX( GAD_SI_QICE2, myThid )
358 diagName = 'ADVx'//diagSufx
359 CALL DIAGNOSTICS_FILL( afx, diagName, 1,1,2,bi,bj, myThid )
360 diagName = 'ADVy'//diagSufx
361 CALL DIAGNOSTICS_FILL( afy, diagName, 1,1,2,bi,bj, myThid )
362 ENDIF
363 #endif
364
365 C-- Update Ice Fraction: ensure that fraction is > iceMaskMin & < 1
366 C and adjust Ice thickness and snow thickness accordingly
367 DO j=1,sNy
368 DO i=1,sNx
369 IF ( iceFrc(i,j) .GT. 1. _d 0 ) THEN
370 iceMask(i,j,bi,bj) = 1. _d 0
371 iceHeight(i,j,bi,bj) = iceHeight(i,j,bi,bj) *iceFrc(i,j)
372 snowHeight(i,j,bi,bj) = snowHeight(i,j,bi,bj)*iceFrc(i,j)
373 ELSEIF ( iceFrc(i,j) .LT. iceMaskMin ) THEN
374 iceMask(i,j,bi,bj) = iceMaskMin
375 iceHeight(i,j,bi,bj) = iceHeight(i,j,bi,bj)
376 & *iceFrc(i,j)*r_minArea
377 snowHeight(i,j,bi,bj) = snowHeight(i,j,bi,bj)
378 & *iceFrc(i,j)*r_minArea
379 ELSE
380 iceMask(i,j,bi,bj) = iceFrc(i,j)
381 ENDIF
382 ENDDO
383 ENDDO
384 C- adjust sea-ice state if not enough ice.
385 DO j=1,sNy
386 DO i=1,sNx
387 IF ( iceHeight(i,j,bi,bj).LT.himin ) THEN
388 C- Not enough ice, melt the tiny amount of snow & ice:
389 C and return fresh-water, salt & energy to the ocean (flx > 0 = into ocean)
390 C- - Note: using 1rst.Order Upwind, I can get the same results as when
391 C using seaice_advdiff (with SEAICEadvScheme=1) providing I comment
392 C out the following lines (and then loose conservation).
393 C- -
394 oceFWfx(i,j,bi,bj) = ( rhos*snowHeight(i,j,bi,bj)
395 & +rhoi*iceHeight(i,j,bi,bj)
396 & )*iceMask(i,j,bi,bj)/thSIce_deltaT
397 oceSflx(i,j,bi,bj) = rhoi*iceHeight(i,j,bi,bj)*saltice
398 & *iceMask(i,j,bi,bj)/thSIce_deltaT
399 oceQnet(i,j,bi,bj) = -( rhos*snowHeight(i,j,bi,bj)*qsnow
400 & +rhoi*iceHeight(i,j,bi,bj)
401 & *( Qice1(i,j,bi,bj)
402 & +Qice2(i,j,bi,bj) )*0.5 _d 0
403 & )*iceMask(i,j,bi,bj)/thSIce_deltaT
404 C- -
405 c flx2oc (i,j) = flx2oc (i,j) +
406 c frw2oc (i,j) = frw2oc (i,j) +
407 c fsalt (i,j) = fsalt (i,j) +
408 iceMask (i,j,bi,bj) = 0. _d 0
409 iceHeight (i,j,bi,bj) = 0. _d 0
410 snowHeight(i,j,bi,bj) = 0. _d 0
411 Qice1 (i,j,bi,bj) = 0. _d 0
412 Qice2 (i,j,bi,bj) = 0. _d 0
413 snowAge (i,j,bi,bj) = 0. _d 0
414 ENDIF
415 ENDDO
416 ENDDO
417
418 #ifdef ALLOW_DBUG_THSICE
419 IF ( dBugFlag ) THEN
420 DO j=1,sNy
421 DO i=1,sNx
422 IF ( dBug(i,j,bi,bj) ) THEN
423 WRITE(6,'(2(A,1P2E14.6))')
424 c & 'ICE_ADV: area_b,a=', AREA(i,j,2,bi,bj),AREA(i,j,1,bi,bj)
425 c WRITE(6,'(A,1P4E14.6)') 'ICE_ADV: mFx=', gFld(i,j)
426 ENDIF
427 ENDDO
428 ENDDO
429 ENDIF
430 #endif
431
432 ELSE
433 C--- if not multiDimAdvection
434
435 WRITE(msgBuf,'(2A)') 'S/R THSICE_ADVDIFF: ',
436 & 'traditional advection/diffusion not yet implemented'
437 CALL PRINT_ERROR( msgBuf , myThid)
438 WRITE(msgBuf,'(2A)') ' ',
439 & 'for ThSice variable Qice1, Qice2, SnowHeight. Sorry!'
440 CALL PRINT_ERROR( msgBuf , myThid)
441 STOP 'ABNORMAL: END: S/R THSICE_ADVDIFF'
442
443 C--- end if multiDimAdvection
444 ENDIF
445
446 #endif /* ALLOW_THSICE */
447
448 RETURN
449 END

  ViewVC Help
Powered by ViewVC 1.1.22