*IF DEF,S40_1A SJC0F305.4
C ******************************COPYRIGHT****************************** GTS2F400.9055
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. GTS2F400.9056
C GTS2F400.9057
C Use, duplication or disclosure of this code is subject to the GTS2F400.9058
C restrictions as set forth in the contract. GTS2F400.9059
C GTS2F400.9060
C Meteorological Office GTS2F400.9061
C London Road GTS2F400.9062
C BRACKNELL GTS2F400.9063
C Berkshire UK GTS2F400.9064
C RG12 2SZ GTS2F400.9065
C GTS2F400.9066
C If no contract has been raised with this copy of the code, the use, GTS2F400.9067
C duplication or disclosure of it is strictly prohibited. Permission GTS2F400.9068
C to do so must first be obtained in writing from the Head of Numerical GTS2F400.9069
C Modelling at the above address. GTS2F400.9070
C ******************************COPYRIGHT****************************** GTS2F400.9071
C GTS2F400.9072
!+ Relaxation routine to correct ice velocities for slab model. SLBICAV.3
! SLBICAV.4
! Subroutine Interface: SLBICAV.5
SUBROUTINE slab_icecavrx( 2,2SLBICAV.6
& imt,jmt,jmtm1,delta_lat,delta_long SLBICAV.7
& ,tol,nmax SLBICAV.8
& ,cos_p_latitude,cos_u_latitude,sec_p_latitude SLBICAV.9
& ,hmask,umask,umc,vmc,ccalc,cavrow SLBICAV.10
& ,ax,ay,bx,by,pmax SLBICAV.11
& ,uice,vice,pressure SLBICAV.12
& ) SLBICAV.13
SLBICAV.14
IMPLICIT NONE SLBICAV.15
! SLBICAV.16
! Description: SLBICAV.17
! DYNAMIC SEA ICE MODEL SUBROUTINE TO CORRECT C GRID FREE DRIFT SLBICAV.18
! VELOCITIES USING THE CAVITATING FLUID ICE RHEOLOGY. SLBICAV.19
! SLBICAV.20
! Method: SLBICAV.21
! Calculate various constants to improve vectorisation of main loop. SLBICAV.22
! Loop over maximum number of iterations. SLBICAV.23
! Copy initial velocities in this loop to workspace. SLBICAV.24
! Loop over each point for which calculations are required. SLBICAV.25
! Calculate divergence of velocity field. SLBICAV.26
! Calculate pressure fiedl increment required prevent convergence, SLBICAV.27
! or reduce pressure within a diverging grid square to zero. SLBICAV.28
! Compare resulting pressure with ice strength and reduce if SLBICAV.29
! necessary. SLBICAV.30
! Calculate velocity increments for each face implied by pressure SLBICAV.31
! correction, masking land and land boundaries. SLBICAV.32
! End loop over grid points. SLBICAV.33
! Loop over grid points and find maximum velocity component SLBICAV.34
! correction for this iteration. Compare with tolerance. SLBICAV.35
! If tolerance exceeds largest velocity correction jump out of loop. SLBICAV.36
! End loop over maximum iterations and print warning if max itertations SLBICAV.37
! was required. SLBICAV.38
! SLBICAV.39
! Current Code Owner: J.F.Thomson SLBICAV.40
! SLBICAV.41
! History: SLBICAV.42
! Version Date Comment SLBICAV.43
! ------- ---- ------- SLBICAV.44
! 3.4 6/94 Original code. J.Thomson SLBICAV.45
! SLBICAV.46
! Code Description: SLBICAV.47
! Language: FORTRAN 77 + common extensions. SLBICAV.48
! This code is written to UMDP3 v6 programming standards. SLBICAV.49
! SLBICAV.50
! System component covered: SLBICAV.51
! System Task: P40 SLBICAV.52
! SLBICAV.53
! Declarations: SLBICAV.54
! These are of the form:- SLBICAV.55
! INTEGER ExampleVariable !Description of variable SLBICAV.56
! SLBICAV.57
! Global variables (*CALLed COMDECKs etc...): SLBICAV.58
*CALL C_A
SLBICAV.59
SLBICAV.60
! Subroutine arguments SLBICAV.61
! Scalar arguments with intent(in): SLBICAV.62
INTEGER imt ! number of columns SLBICAV.63
INTEGER jmt ! number of rows SLBICAV.64
INTEGER jmtm1 ! number of rows minus 1 SLBICAV.65
REAL delta_lat ! zonal grid spacing in radians SLBICAV.66
REAL delta_long ! merid. grid spacing in radians SLBICAV.67
REAL tol ! tolerance for correction scheme SLBICAV.68
INTEGER nmax ! maximum iterations SLBICAV.69
SLBICAV.70
! Array arguments with intent(in): SLBICAV.71
REAL cos_p_latitude(imt,jmt) ! cos latitude on p pts SLBICAV.72
REAL cos_u_latitude(imt,jmtm1)! cos latitude on p pts SLBICAV.73
REAL sec_p_latitude(imt,jmt) ! 1/(cos latitude) on p pts SLBICAV.74
REAL hmask(imt,jmt) ! 1. for sea 0. for land p pts SLBICAV.75
REAL umask(imt,jmtm1) ! 1. for sea 0. for land uv pts SLBICAV.76
REAL umc(imt,jmtm1) ! 1. for sea 0. for land cu pts SLBICAV.77
REAL vmc(imt,jmtm1) ! 1. for sea 0. for land cv pts SLBICAV.78
REAL ax(imt,jmtm1) ! cdw * sin(psi) for C x pts SLBICAV.79
REAL ay(imt,jmtm1) ! cdw * sin(psi) for C y pts SLBICAV.80
REAL bx(imt,jmtm1) ! mf+cdw*cos(psi) for C x pts SLBICAV.81
REAL by(imt,jmtm1) ! mf+cdw*cos(psi) for C y pts SLBICAV.82
& ! m is gbm ice depth * rhoice SLBICAV.83
& ! f is coriolis parameter SLBICAV.84
REAL pmax(imt,jmt) ! ice strength (max pressure) SLBICAV.85
LOGICAL ccalc(imt,jmt) ! true if dynamics calcs needed SLBICAV.86
LOGICAL cavrow(jmt) ! true if dynamics calcs needed SLBICAV.87
SLBICAV.88
! Scalar arguments with intent(InOut): SLBICAV.89
SLBICAV.90
! Array arguments with intent(InOut): SLBICAV.91
REAL uice(imt,jmtm1) ! x ice vel. component (C grid) SLBICAV.92
REAL vice(imt,jmtm1) ! y ice vel. component (C grid) SLBICAV.93
REAL pressure(imt,jmt) ! internal ice pressure SLBICAV.94
SLBICAV.95
! Scalar arguments with intent(out): SLBICAV.96
SLBICAV.97
! Array arguments with intent(out): SLBICAV.98
SLBICAV.99
! Local parameters: SLBICAV.100
REAL zero ! 0.0 SLBICAV.101
PARAMETER ( zero = 0.0 ) SLBICAV.102
REAL cos_80_deg ! cos ( 80 degrees ) SLBICAV.103
PARAMETER ( cos_80_deg = 0.1736 ) SLBICAV.104
SLBICAV.105
! Local scalars: SLBICAV.106
INTEGER imtm1 ! number of columns minus 1 SLBICAV.107
INTEGER imtm2 ! number of columns minus 2 SLBICAV.108
INTEGER i,j,n,istart ! loop counters SLBICAV.109
INTEGER i1,j1 ! pointers SLBICAV.110
INTEGER iter ! iteration count SLBICAV.111
INTEGER niter ! iteration count for polar rows SLBICAV.112
REAL errm,erru,errv ! error terms in iteration SLBICAV.113
REAL pcorr,delp ! pressure corrections SLBICAV.114
REAL rdlat ! recip of merid grid spacing SLBICAV.115
REAL rdlon ! recip of zonal grid spacing SLBICAV.116
REAL t1 ! intermediate value in calc SLBICAV.117
REAL pdiff ! pressure gradient SLBICAV.118
REAL duij,duip1j,dvij,dvijp1 ! velocity increments SLBICAV.119
REAL div ! divergence at a point SLBICAV.120
SLBICAV.121
! Local dynamic arrays: SLBICAV.122
REAL uwork(imt,jmtm1) ! work array for u ice velocity. SLBICAV.123
REAL vwork(imt,jmtm1) ! work array for v ice velocity. SLBICAV.124
REAL con1(imt,jmt),con2(imt,jmt),con3(imt,jmt),dmlt(imt,jmt) SLBICAV.125
REAL con5(imt,jmt),con6(imt,jmt),con7(imt,jmt),con8(imt,jmt) SLBICAV.126
REAL con9(imt,jmt) SLBICAV.127
SLBICAV.128
! Function & Subroutine calls: SLBICAV.129
External timer SLBICAV.130
SLBICAV.131
!- End of header SLBICAV.132
*IF DEF,TIMER SLBICAV.133
call timer
('icecavrx',3) SLBICAV.134
*ENDIF SLBICAV.135
imtm1=imt-1 SLBICAV.136
imtm2=imt-2 SLBICAV.137
rdlat=1.0/delta_lat SLBICAV.138
rdlon=1.0/delta_long SLBICAV.139
SLBICAV.140
! Initialise arrays for use in cavitating fluid calculations SLBICAV.141
do j=1,jmt ! start j loop SLBICAV.142
do i=1,imt ! start i loop SLBICAV.143
con1(i,j)=1.0/a*cos_p_latitude(i,j) SLBICAV.144
con2(i,j)=zero SLBICAV.145
con3(i,j)=zero SLBICAV.146
dmlt(i,j)=zero SLBICAV.147
con5(i,j)=zero SLBICAV.148
con6(i,j)=zero SLBICAV.149
con7(i,j)=zero SLBICAV.150
con8(i,j)=zero SLBICAV.151
con9(i,j)=zero SLBICAV.152
end do ! end i loop SLBICAV.153
end do ! end j loop SLBICAV.154
do j=1,jmtm1 ! start j loop SLBICAV.155
j1=j+1 SLBICAV.156
do i=1,imt ! start i loop SLBICAV.157
i1=i+1 SLBICAV.158
if (i1.gt.imt) i1=i1-imt SLBICAV.159
if (abs(ax(i,j)).gt.1.0e-4) then SLBICAV.160
con2(i,j) = (1.0/ax(i,j))*sec_p_latitude(i1,j1) SLBICAV.161
con5(i,j) = (con1(i1,j1)*rdlon)/ax(i,j) SLBICAV.162
endif SLBICAV.163
if (abs(ay(i,j)).gt.1.0e-4) then SLBICAV.164
con3(i,j) = cos_u_latitude(i,j)/ay(i,j) SLBICAV.165
con7(i,j) = rdlat/(a*ay(i,j)) SLBICAV.166
endif SLBICAV.167
if (abs(ax(i1,j)).gt.1.0e-4) SLBICAV.168
& con6(i,j) = (con1(i1,j1)*rdlon)/ax(i1,j) SLBICAV.169
if (abs(ay(i,j1)).gt.1.0e-4) SLBICAV.170
& con8(i,j) = rdlat/(a*ay(i,j1)) SLBICAV.171
end do ! end i loop SLBICAV.172
end do ! end j loop SLBICAV.173
do j=1,jmtm1 ! start j loop SLBICAV.174
j1=j+1 SLBICAV.175
do i=1,imt ! start i loop SLBICAV.176
i1=i+1 SLBICAV.177
if (i1.gt.imt) i1=i1-imt SLBICAV.178
t1 = SLBICAV.179
& ( ( con2(i1,j)+con2(i,j) ) SLBICAV.180
& *rdlon*rdlon SLBICAV.181
& + (con3(i,j1)+con3(i,j))*rdlat*rdlat ) SLBICAV.182
if ( abs(t1) .gt. 1.0e-4 ) SLBICAV.183
& con9(i,j) = a*a*cos_p_latitude(i1,j1)/t1 SLBICAV.184
end do ! end i loop SLBICAV.185
end do ! end j loop SLBICAV.186
SLBICAV.187
! Cavitating Fluid Correction Scheme SLBICAV.188
! Repeat correction up to nmax times SLBICAV.189
do iter=1,nmax ! start iter loop SLBICAV.190
errm = zero SLBICAV.191
! Copy initial velocities to workspace SLBICAV.192
do j=1,jmtm1 ! start j loop SLBICAV.193
do i=1,imt ! start i loop SLBICAV.194
uwork(i,j) = uice(i,j) * umc(i,j) SLBICAV.195
vwork(i,j) = vice(i,j) * vmc(i,j) SLBICAV.196
end do ! end i loop SLBICAV.197
*IF DEF,OCYCLIC SLBICAV.198
uwork(imt,j) = uwork(2,j) SLBICAV.199
uwork(1,j) = uwork(imtm1,j) SLBICAV.200
vwork(imt,j) = vwork(2,j) SLBICAV.201
vwork(1,j) = vwork(imtm1,j) SLBICAV.202
*ENDIF SLBICAV.203
end do ! end j loop SLBICAV.204
! Loop over computational grid SLBICAV.205
do j=1,jmt-2 ! start j loop SLBICAV.206
j1=j+1 SLBICAV.207
if (cavrow(j1)) then SLBICAV.208
niter=1 SLBICAV.209
if ( cos_u_latitude(1,j1) .lt. cos_80_deg ) niter = 20 SLBICAV.210
do n=1,niter ! start n loop SLBICAV.211
do istart=2,3 ! start istart loop SLBICAV.212
do i=istart,imtm1,2 ! start i loop SLBICAV.213
i1 = i+1 SLBICAV.214
delp = zero SLBICAV.215
pcorr = zero SLBICAV.216
div = zero SLBICAV.217
div = ( (uice(i1,j)-uice(i,j)) * rdlon SLBICAV.218
& + ( vice(i,j1)*cos_u_latitude(i,j1) SLBICAV.219
& - vice(i,j)*cos_u_latitude(i,j) ) * rdlat ) SLBICAV.220
& * con1(i1,j1) SLBICAV.221
pcorr = -div * con9(i,j) * hmask(i1,j1) SLBICAV.222
if ( div .le. zero ) then SLBICAV.223
delp = pcorr SLBICAV.224
endif SLBICAV.225
! Test ice pressure against ice strength, pmax. SLBICAV.226
pdiff = pmax(i1,j1) - ( pressure(i1,j1) + delp ) SLBICAV.227
if (pdiff.lt.zero) delp=pmax(i1,j1)-pressure(i1,j1) SLBICAV.228
if (div.gt.zero .and. pressure(i1,j1).le.zero) then SLBICAV.229
delp = zero SLBICAV.230
elseif (div.gt.zero.and.pressure(i1,j1).gt.zero) then SLBICAV.231
delp = max(pcorr,-pressure(i1,j1)) SLBICAV.232
endif SLBICAV.233
! Calculate velocity corrections. SLBICAV.234
duij = -delp*con5(i,j) SLBICAV.235
duip1j = delp*con6(i,j) SLBICAV.236
dvij = -delp*con7(i,j) SLBICAV.237
dvijp1 = delp*con8(i,j) SLBICAV.238
! Add corrections to velocities. SLBICAV.239
uice(i,j) = (uice(i,j)+duij) * umc(i,j) SLBICAV.240
uice(i1,j) = (uice(i1,j)+duip1j) * umc(i1,j) SLBICAV.241
vice(i,j) = (vice(i,j)+dvij) * vmc(i,j) SLBICAV.242
vice(i,j1) = (vice(i,j1)+dvijp1) * vmc(i,j1) SLBICAV.243
! Calculate new ice pressure. SLBICAV.244
pressure(i1,j1) = pressure(i1,j1) + delp SLBICAV.245
! End loop SLBICAV.246
end do ! end i loop SLBICAV.247
*IF DEF,OCYCLIC SLBICAV.248
uice(1,j) = uice(imtm1,j) SLBICAV.249
uice(imt,j) = uice(2,j) SLBICAV.250
vice(1,j) = vice(imtm1,j) SLBICAV.251
vice(imt,j) = vice(2,j) SLBICAV.252
vice(1,j1) = vice(imtm1,j1) SLBICAV.253
vice(imt,j1) = vice(2,j1) SLBICAV.254
pressure(1,j1) = pressure(imtm1,j1) SLBICAV.255
pressure(imt,j1)= pressure(2,j1) SLBICAV.256
*ENDIF SLBICAV.257
end do ! end istart loop SLBICAV.258
end do ! end n loop SLBICAV.259
endif SLBICAV.260
end do ! end j loop SLBICAV.261
! Check maximum error and jump out of loop if this is within the SLBICAV.262
! tolerance set above. SLBICAV.263
errm = zero SLBICAV.264
do j = 1,jmt-2 ! start j loop SLBICAV.265
if (cavrow(j+1)) then SLBICAV.266
do i = 2,imtm1 ! start i loop SLBICAV.267
erru = abs(uice(i,j)-uwork(i,j)) SLBICAV.268
errv = abs(vice(i,j)-vwork(i,j)) SLBICAV.269
errm = max(errm,erru,errv) SLBICAV.270
end do ! end i loop SLBICAV.271
endif SLBICAV.272
end do ! end j loop SLBICAV.273
if ( errm .lt. tol ) go to 999 SLBICAV.274
! End loop over maximum iterations SLBICAV.275
end do ! end iter loop SLBICAV.276
if (iter.ge.nmax) write(6,*) SLBICAV.277
& 'Maximum number of iterations exceeded in correction scheme' SLBICAV.278
999 continue SLBICAV.279
write(6,*) 'Number of iterations in correction scheme = ',iter SLBICAV.280
*IF DEF,OCYCLIC SLBICAV.281
SLBICAV.282
! Make velocities cyclic if necessary SLBICAV.283
do j=1,jmtm1 SLBICAV.284
uice(1,j) = uice(imtm1,j) SLBICAV.285
uice(imt,j) = uice(2,j) SLBICAV.286
vice(1,j) = vice(imtm1,j) SLBICAV.287
vice(imt,j) = vice(2,j) SLBICAV.288
end do SLBICAV.289
*ENDIF SLBICAV.290
SLBICAV.291
*IF DEF,TIMER SLBICAV.292
call timer
('icecavrx',4) SLBICAV.293
*ENDIF SLBICAV.294
return SLBICAV.295
end SLBICAV.296
*ENDIF SLBICAV.297