*IF DEF,S40_1A SJC0F305.7
C ******************************COPYRIGHT****************************** GTS2F400.9127
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. GTS2F400.9128
C GTS2F400.9129
C Use, duplication or disclosure of this code is subject to the GTS2F400.9130
C restrictions as set forth in the contract. GTS2F400.9131
C GTS2F400.9132
C Meteorological Office GTS2F400.9133
C London Road GTS2F400.9134
C BRACKNELL GTS2F400.9135
C Berkshire UK GTS2F400.9136
C RG12 2SZ GTS2F400.9137
C GTS2F400.9138
C If no contract has been raised with this copy of the code, the use, GTS2F400.9139
C duplication or disclosure of it is strictly prohibited. Permission GTS2F400.9140
C to do so must first be obtained in writing from the Head of Numerical GTS2F400.9141
C Modelling at the above address. GTS2F400.9142
C ******************************COPYRIGHT****************************** GTS2F400.9143
C GTS2F400.9144
!+ Subroutine calculates free drift ice velocity for SLAB ocean. SLBIFREE.3
! SLBIFREE.4
! Subroutine Interface: SLBIFREE.5
SUBROUTINE slab_icefreec( 2,2SLBIFREE.6
& imt,jmt,jmtm1,lglobal SLBIFREE.7
&,tol,nmax,weight SLBIFREE.8
&,delta_lat,delta_long SLBIFREE.9
&,cos_p_latitude,umask,ccalc SLBIFREE.10
&,umc,vmc,pressure SLBIFREE.11
&,ax,ay,bx,by SLBIFREE.12
&,x_stress,y_stress SLBIFREE.13
&,uice,vice SLBIFREE.14
& ) SLBIFREE.15
SLBIFREE.16
IMPLICIT NONE SLBIFREE.17
! SLBIFREE.18
! Description: SLBIFREE.19
! DYNAMIC SEA ICE MODEL SUBROUTINE TO CALCULATE MODIFIED FREE SLBIFREE.20
! DRIFT ICE VELOCITIES IN C GRID WITH GIVEN PRESSURE. SLBIFREE.21
! SLBIFREE.22
! Method: SLBIFREE.23
! Loop over maximum number of iterations. SLBIFREE.24
! Copy initial velocities for this sweep to workspace. SLBIFREE.25
! Loop over each point in grid requiring free drift calculation SLBIFREE.26
! using chequerboard scheme to improve vectorisation. SLBIFREE.27
! C grid free drift underrelaxation scheme. SLBIFREE.28
! See documentation (to be released - contact J. Thomson) SLBIFREE.29
! for details of calculation. SLBIFREE.30
! End loop over grid. SLBIFREE.31
! Calculate maximum velocity change in this iteration and compare SLBIFREE.32
! with tolerance. If tolerance exceeds max change, jump out of SLBIFREE.33
! loop. SLBIFREE.34
! End loop over max iterations, printing warning if max iterations SLBIFREE.35
! reached SLBIFREE.36
! SLBIFREE.37
! Current Code Owner: J.F.Thomson SLBIFREE.38
! SLBIFREE.39
! History: SLBIFREE.40
! Version Date Comment SLBIFREE.41
! ------- ---- ------- SLBIFREE.42
! 3.4 6/94 Original code. J.Thomson SLBIFREE.43
! SLBIFREE.44
! Code Description: SLBIFREE.45
! Language: FORTRAN 77 + common extensions. SLBIFREE.46
! This code is written to UMDP3 v6 programming standards. SLBIFREE.47
! SLBIFREE.48
! System component covered: SLBIFREE.49
! System Task: P40 SLBIFREE.50
! SLBIFREE.51
! Declarations: SLBIFREE.52
! These are of the form:- SLBIFREE.53
! INTEGER ExampleVariable !Description of variable SLBIFREE.54
! SLBIFREE.55
! Global variables (*CALLed COMDECKs etc...): SLBIFREE.56
*CALL C_A
SLBIFREE.57
SLBIFREE.58
! Subroutine arguments SLBIFREE.59
! Scalar arguments with intent(in): SLBIFREE.60
INTEGER imt ! number of tracer columns. SLBIFREE.61
INTEGER jmt ! number of tracer rows. SLBIFREE.62
INTEGER jmtm1 ! number of velocity rows. SLBIFREE.63
LOGICAL lglobal ! true for global models. SLBIFREE.64
REAL delta_lat ! meridional grid spacing in radians. SLBIFREE.65
REAL delta_long ! zonal grid spacing in radians. SLBIFREE.66
REAL weight ! weighting term for C grid calc. SLBIFREE.67
REAL tol ! tolerance for C grid calc. SLBIFREE.68
INTEGER nmax ! maximum iterations SLBIFREE.69
SLBIFREE.70
! Array arguments with intent(in): SLBIFREE.71
REAL cos_p_latitude(imt,jmt) ! cosine of p grid points. SLBIFREE.72
REAL umask(imt,jmtm1) ! in 1.0 for uv land 0.0 for sea. SLBIFREE.73
REAL umc(imt,jmtm1) ! in 1.0 for cu land 0.0 for sea. SLBIFREE.74
REAL vmc(imt,jmtm1) ! in 1.0 for cv land 0.0 for sea. SLBIFREE.75
LOGICAL ccalc(imt,jmt) ! true if C grid calcs required. SLBIFREE.76
REAL pressure(imt,jmtm1) ! internal ice pressure. SLBIFREE.77
REAL x_stress(imt,jmtm1) ! zonal stress on ice (C grid) SLBIFREE.78
REAL y_stress(imt,jmtm1) ! merid. stress on ice (C grid) SLBIFREE.79
REAL ax(imt,jmtm1) ! cdw * sin(psi) for C x pts SLBIFREE.80
REAL ay(imt,jmtm1) ! cdw * sin(psi) for C y pts SLBIFREE.81
REAL bx(imt,jmtm1) ! mf + cdw * cos(psi) for C x pts SLBIFREE.82
REAL by(imt,jmtm1) ! mf + cdw * cos(psi) for C y pts SLBIFREE.83
& ! m = gbm ice depth * rhoice SLBIFREE.84
& ! f = coriolis parameter SLBIFREE.85
SLBIFREE.86
! Scalar arguments with intent(InOut): SLBIFREE.87
SLBIFREE.88
! Array arguments with intent(InOut): SLBIFREE.89
REAL uice(imt,jmtm1) ! zonal sea ice velocity. SLBIFREE.90
REAL vice(imt,jmtm1) ! meridional sea ice velocity. SLBIFREE.91
SLBIFREE.92
! Scalar arguments with intent(out): SLBIFREE.93
SLBIFREE.94
! Array arguments with intent(out): SLBIFREE.95
SLBIFREE.96
! Local parameters: SLBIFREE.97
REAL zero ! 0.0 SLBIFREE.98
PARAMETER ( zero = 0.0 ) SLBIFREE.99
REAL fr1 ! 1/4 as used in relaxation SLBIFREE.100
PARAMETER ( fr1 = 0.25 ) SLBIFREE.101
REAL fr2 ! 1/16 as used in relaxation SLBIFREE.102
PARAMETER ( fr2 = 0.0625 ) SLBIFREE.103
SLBIFREE.104
! Local scalars: SLBIFREE.105
REAL r1 ! term in C grid calc SLBIFREE.106
REAL r2 ! term in C grid calc SLBIFREE.107
REAL rdet ! term in C grid calc SLBIFREE.108
REAL det ! term in C grid calc SLBIFREE.109
REAL errm ! error term in C grid calc SLBIFREE.110
REAL erru ! error term in C grid calc SLBIFREE.111
REAL errv ! error term in C grid calc SLBIFREE.112
REAL dpdx ! pressure gradient SLBIFREE.113
REAL dpdy ! pressure gradient SLBIFREE.114
INTEGER imtm1 ! number of columns minus 1 SLBIFREE.115
INTEGER imtm2 ! number of columns minus 2 SLBIFREE.116
INTEGER i,j,istart,iter ! loop counters SLBIFREE.117
SLBIFREE.118
! Local dynamic arrays: SLBIFREE.119
REAL uwork(imt,jmtm1) ! work array for u ice velocity. SLBIFREE.120
REAL vwork(imt,jmtm1) ! work array for v ice velocity. SLBIFREE.121
SLBIFREE.122
! Function & Subroutine calls: SLBIFREE.123
! External SLBIFREE.124
SLBIFREE.125
!- End of header SLBIFREE.126
*IF DEF,TIMER SLBIFREE.127
call timer
('icefreec',3) SLBIFREE.128
*ENDIF SLBIFREE.129
imtm1=imt-1 SLBIFREE.130
imtm2=imt-2 SLBIFREE.131
SLBIFREE.132
! Iterative C grid 'free drift' velocity calculations SLBIFREE.133
! Begin loop over maximum number of iterations SLBIFREE.134
do iter=1,nmax SLBIFREE.135
SLBIFREE.136
! Copy initial velocities to work space SLBIFREE.137
do j=1,jmtm1 SLBIFREE.138
do i=1,imt SLBIFREE.139
uwork(i,j) = uice(i,j) SLBIFREE.140
vwork(i,j) = vice(i,j) SLBIFREE.141
end do SLBIFREE.142
end do SLBIFREE.143
! SLBIFREE.144
! Calculate velocity components using w as a weight. SLBIFREE.145
! SLBIFREE.146
do j=2,jmt-2 SLBIFREE.147
do istart=2,3 SLBIFREE.148
do i=istart,imtm1,2 SLBIFREE.149
if(ccalc(i+1,j+1)) then SLBIFREE.150
dpdx = ( pressure(i+1,j+1) - pressure(i,j+1) ) SLBIFREE.151
& / ( a * cos_p_latitude(i+1,j+1) * delta_long ) SLBIFREE.152
dpdy = ( pressure(i+1,j+1) - pressure(i+1,j) ) SLBIFREE.153
& / ( a * delta_lat ) SLBIFREE.154
r1 = dpdx - x_stress(i,j) - fr1 * bx(i,j) SLBIFREE.155
& *(vice(i-1,j) + vice(i-1,j+1) + vice(i,j+1) ) SLBIFREE.156
r2 = dpdy - y_stress(i,j) + fr1 * by(i,j) SLBIFREE.157
& *(uice(i+1,j) + uice(i,j-1) + uice(i+1,j-1) ) SLBIFREE.158
det = ( ax(i,j)*ay(i,j) + bx(i,j)*by(i,j)*fr2 ) SLBIFREE.159
if ( abs(det) .lt. 1.0e-6 ) then SLBIFREE.160
rdet = zero SLBIFREE.161
else SLBIFREE.162
rdet = 1. / det SLBIFREE.163
endif SLBIFREE.164
uice(i,j) = (weight*rdet*( -ay(i,j)*r1 - bx(i,j)*r2*fr1 ) SLBIFREE.165
& + (1.0-weight) * uwork(i,j) ) * umc(i,j) SLBIFREE.166
vice(i,j) = (weight*rdet*( -ax(i,j)*r2 + by(i,j)*r1*fr1 ) SLBIFREE.167
& + (1.0-weight) * vwork(i,j) ) * vmc(i,j) SLBIFREE.168
else SLBIFREE.169
uice(i,j)=0.0 SLBIFREE.170
vice(i,j)=0.0 SLBIFREE.171
endif SLBIFREE.172
end do SLBIFREE.173
end do SLBIFREE.174
end do SLBIFREE.175
do j=2,jmt-2 SLBIFREE.176
if (lglobal) then SLBIFREE.177
if(ccalc(2,j+1)) then SLBIFREE.178
dpdx = ( pressure(2,j+1) - pressure(1,j+1) ) SLBIFREE.179
& / ( a * cos_p_latitude(2,j+1) * delta_long ) SLBIFREE.180
dpdy = ( pressure(2,j+1) - pressure(2,j) ) SLBIFREE.181
& / ( a * delta_lat ) SLBIFREE.182
r1 = dpdx - x_stress(1,j) - fr1 * bx(1,j) SLBIFREE.183
& *(vice(imt,j) + vice(imt,j+1) + vice(1,j+1) ) SLBIFREE.184
r2 = dpdy - y_stress(1,j) + fr1 * by(1,j) SLBIFREE.185
& *(uice(2,j) + uice(1,j-1) + uice(2,j-1) ) SLBIFREE.186
det = ( ax(1,j)*ay(1,j) + bx(1,j)*by(1,j)*fr2 ) SLBIFREE.187
if ( abs(det) .lt. 1.0e-6 ) then SLBIFREE.188
rdet = zero SLBIFREE.189
else SLBIFREE.190
rdet = 1. / det SLBIFREE.191
endif SLBIFREE.192
uice(1,j) = (weight*rdet*(-ay(1,j)*r1 - bx(1,j)*r2*fr1) SLBIFREE.193
& + (1.0-weight) * uwork(1,j) ) * umc(1,j) SLBIFREE.194
vice(1,j) = (weight*rdet*(-ax(1,j)*r2 + by(1,j)*r1*fr1) SLBIFREE.195
& + (1.0-weight) * vwork(1,j) ) * vmc(1,j) SLBIFREE.196
else SLBIFREE.197
uice(1,j)=0.0 SLBIFREE.198
vice(1,j)=0.0 SLBIFREE.199
endif SLBIFREE.200
if(ccalc(1,j+1)) then SLBIFREE.201
dpdx = ( pressure(1,j+1) - pressure(imt,j+1) ) SLBIFREE.202
& / ( a * cos_p_latitude(1,j+1) * delta_long ) SLBIFREE.203
dpdy = ( pressure(1,j+1) - pressure(1,j) ) SLBIFREE.204
& / ( a * delta_lat ) SLBIFREE.205
r1 = dpdx - x_stress(imt,j) - fr1 * bx(imt,j) SLBIFREE.206
& *(vice(imtm1,j) + vice(imtm1,j+1) + vice(imt,j+1) ) SLBIFREE.207
r2 = dpdy - y_stress(imt,j) + fr1 * by(imt,j) SLBIFREE.208
& *(uice(1,j) + uice(imt,j-1) + uice(1,j-1) ) SLBIFREE.209
det = (ax(imt,j)*ay(imt,j) + bx(imt,j)*by(imt,j)*fr2) SLBIFREE.210
if ( abs(det) .lt. 1.0e-6 ) then SLBIFREE.211
rdet = zero SLBIFREE.212
else SLBIFREE.213
rdet = 1. / det SLBIFREE.214
endif SLBIFREE.215
uice(imt,j) = (weight*rdet*(-ay(imt,j)*r1 - bx(imt,j)*r2*fr1) SLBIFREE.216
& + (1.0-weight) * uwork(imt,j) ) * umc(imt,j) SLBIFREE.217
vice(imt,j) = (weight*rdet*(-ax(imt,j)*r2 + by(imt,j)*r1*fr1) SLBIFREE.218
& + (1.0-weight) * vwork(imt,j) ) * vmc(imt,j) SLBIFREE.219
else SLBIFREE.220
uice(imt,j)=0.0 SLBIFREE.221
vice(imt,j)=0.0 SLBIFREE.222
endif SLBIFREE.223
else SLBIFREE.224
uice(1,j)=0.0 SLBIFREE.225
vice(1,j)=0.0 SLBIFREE.226
uice(imt,j)=0.0 SLBIFREE.227
vice(imt,j)=0.0 SLBIFREE.228
endif SLBIFREE.229
end do SLBIFREE.230
! Check maximum error and jump out of loop if this is within the SLBIFREE.231
! tolerance set above. SLBIFREE.232
errm = zero SLBIFREE.233
do j = 2,jmt-2 SLBIFREE.234
do i = 1,imt SLBIFREE.235
erru = abs(uice(i,j)-uwork(i,j)) SLBIFREE.236
errv = abs(vice(i,j)-vwork(i,j)) SLBIFREE.237
if (erru .gt. errm) errm=erru SLBIFREE.238
if (errv .gt. errm) errm=errv SLBIFREE.239
end do SLBIFREE.240
end do SLBIFREE.241
if (errm .le. tol) go to 888 SLBIFREE.242
! End loop over maximum iterations SLBIFREE.243
end do SLBIFREE.244
if (iter.ge.nmax) write(6,*) SLBIFREE.245
& 'Maximum number of iterations exceeded in free drift calc.' SLBIFREE.246
888 continue SLBIFREE.247
write(6,*) 'Number of iterations in free drift calc = ',iter SLBIFREE.248
! Copy velocities from adjacent rows into rows 1 and jmtm1 SLBIFREE.249
do i=1,imt SLBIFREE.250
uice(i,1) = uice(i,2)*umc(i,1) SLBIFREE.251
uice(i,jmtm1) = uice(i,jmt-2)*umc(i,jmtm1) SLBIFREE.252
vice(i,1) = vice(i,2)*vmc(i,1) SLBIFREE.253
vice(i,jmtm1) = vice(i,jmt-2)*vmc(i,jmtm1) SLBIFREE.254
end do SLBIFREE.255
*IF DEF,TIMER SLBIFREE.256
call timer
('icefreec',4) SLBIFREE.257
*ENDIF SLBIFREE.258
return SLBIFREE.259
end SLBIFREE.260
*ENDIF SLBIFREE.261