*IF DEF,OCEAN CGRELAX.2
C ******************************COPYRIGHT****************************** CGRELAX.3
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. CGRELAX.4
C CGRELAX.5
C Use, duplication or disclosure of this code is subject to the CGRELAX.6
C restrictions as set forth in the contract. CGRELAX.7
C CGRELAX.8
C Meteorological Office CGRELAX.9
C London Road CGRELAX.10
C BRACKNELL CGRELAX.11
C Berkshire UK CGRELAX.12
C RG12 2SZ CGRELAX.13
C CGRELAX.14
C If no contract has been raised with this copy of the code, the use, CGRELAX.15
C duplication or disclosure of it is strictly prohibited. Permission CGRELAX.16
C to do so must first be obtained in writing from the Head of Numerical CGRELAX.17
C Modelling at the above address. CGRELAX.18
C ******************************COPYRIGHT****************************** CGRELAX.19
C ****************************ACKNOWLEDGMENT*************************** CGRELAX.20
C This code is derived from Public Domain code (the Cox 1984 Ocean CGRELAX.21
C Model) distributed by the Geophysical Fluid Dynamics Laboratory. CGRELAX.22
C NOAA CGRELAX.23
C PO Box 308 CGRELAX.24
C Princeton CGRELAX.25
C New Jersey USA CGRELAX.26
C If you wish to obtain a copy of the original code that does not have CGRELAX.27
C Crown Copyright use, duplication or disclosure restrictions, please CGRELAX.28
C contact them at the above address. CGRELAX.29
C ****************************ACKNOWLEDGMENT*************************** CGRELAX.30
C CGRELAX.31
SUBROUTINE CG_RELAX( 1,16CGRELAX.32
*CALL ARGSIZE
CGRELAX.33
*CALL ARGOCALL
CGRELAX.34
*CALL ARGOINDX
ORH5F402.2
& P,PB,PTD,PTDB ORH3F405.88
&,FDIR,HDIR CGRELAX.37
&,ZTD CGRELAX.38
& ) CGRELAX.39
! for correct operation fdir and hdir should be given as arguments and CGRELAX.40
! thus passed into the dump, and set to zero in the dump for a new run. CGRELAX.41
CGRELAX.42
C----------------------------------------------------------------------- CGRELAX.43
CLL MODEL Date MODIFICATION HISTORY FROM MODEL VERSION 3.4 CGRELAX.44
CLL VERSION CGRELAX.45
CLL 4.1 14.5.96 Complete solver re-write to use CG (KAH) CGRELAX.46
CLL CGRELAX.47
CLL CGRELAX.48
C----------------------------------------------------------------------- CGRELAX.49
C CG_RELAX takes as input the vorticity driving function computed in CGRELAX.50
C "clinic" (ZTD) and, using conjugate gradient iteration CGRELAX.51
C solves the Laplacian equation for the external mode of CGRELAX.52
C velocity in terms of a mass transport stream function (P). CGRELAX.53
C CGRELAX.54
C For information on the method used in this code see: CGRELAX.55
C (for example) R. Barrett et al "Templates for the Solution CGRELAX.56
C of Linear Systems: Building Blocks for Iterative Methods" CGRELAX.57
C Society for Industrial and Applied Mathematics (1994). CGRELAX.58
C CGRELAX.59
C----------------------------------------------------------------------- CGRELAX.60
IMPLICIT NONE CGRELAX.61
CGRELAX.62
C Define global data: CGRELAX.63
*CALL TYPSIZE
CGRELAX.64
*CALL TYPOINDX
PXORDER.9
*CALL TYPOCALL
CGRELAX.65
*CALL UMSCALAR
CGRELAX.66
*CALL CNTLOCN
CGRELAX.67
*CALL OARRYSIZ
CGRELAX.68
*CALL OTIMER
CGRELAX.69
CGRELAX.70
C Define argument list: CGRELAX.71
REAL ORH3F405.90
& P(IMT_STREAM,0:JMT_STREAM+1), !stream function ORH1F402.50
& PB(IMT_STREAM,0:JMT_STREAM+1), !stream function at prev tstep ORH1F402.51
& PTD(IMT_STREAM,JMT_STREAM), !chng in strm fn across timestep CGRELAX.77
& PTDB(IMT_STREAM,JMT_STREAM), !chng in strm fn across prvs tstep CGRELAX.78
& ZTD(IMT_STREAM,JMT_STREAM) !Vorticity change across timesteps CGRELAX.79
CGRELAX.80
C Define local variables: CGRELAX.81
REAL FX, ! Temporary value CGRELAX.82
& FXA, ! Temporary value CGRELAX.83
& FXB, ! Temporary value CGRELAX.84
& FXC, ! Temporary value CGRELAX.85
& FXD, ! Temporary value CGRELAX.86
& CRTP, ! Altered val of CRIT (convergence criteria) CGRELAX.87
& RESMAX ! Max of residuals at all grid points CGRELAX.88
CGRELAX.89
INTEGER ORH3F405.89
& I, ! Grid point index (Zonal) CGRELAX.91
& J, ! Grid point index (Meridonal) CGRELAX.92
& L, ! Loop control for ocean segment CGRELAX.93
& IE, ! End index for I loop CGRELAX.94
& IS ! Start index for I loop CGRELAX.95
CGRELAX.96
REAL CGRELAX.97
& RESIS, ! Residual of relaxation of island CGRELAX.98
& RESIS_ROW(JMT), ! Residual of relaxation of island ORH5F402.196
& TEST1, ! Product of reciprocals of 4 surrounding depths CGRELAX.99
& TEST2 ! Sum of reciprocals of 4 surrounding depths CGRELAX.100
CGRELAX.101
REAL CGRELAX.102
& CFN(IMT,JMT), ! coefficients in Laplacian star stencil CGRELAX.103
& CFS(IMT,JMT), ! (north, south, east, west etc) CGRELAX.104
& CFE(IMT,JMT), CGRELAX.105
& CFW(IMT,JMT), CGRELAX.106
& RES(IMT,JMT), ! residual CGRELAX.107
& COF(IMT,JMT), ! normalising coefficient CGRELAX.108
& COFIS(NISLE), CGRELAX.109
& COFIS_ROW(JMT), ORH5F402.197
& CPF(IMT,JMT), ! normalisation factor for Laplacian stencil CGRELAX.110
& H(IMT,JMT) ! total depth at UV points CGRELAX.111
CGRELAX.112
INTEGER CGRELAX.113
& ISLE, ! Do loop index indicates current island CGRELAX.114
& JE, ! End index for J loop CGRELAX.115
& JS, ! Start index for J loop CGRELAX.116
& N, ! Do loop index for island segments CGRELAX.117
& NSEG, ! End index for island segment DO loops CGRELAX.118
& ISMASK(IMT,JMT) ! grid point type indicator CGRELAX.119
! (0=interior, 1=perimeter, 2=land) CGRELAX.120
& ,INFO ! MPP call info ORH5F402.4
CGRELAX.121
C Definitions for Conjugate gradient: CGRELAX.122
REAL CGRELAX.123
& GDIR(IMT,JMT), ! CG gradient directions etc CGRELAX.124
& FDIR(IMT,JMT), CGRELAX.125
& HDIR(IMT,JMT) CGRELAX.126
REAL ASUM(JMT) ! used for temporary sums CGRELAX.127
REAL beta, ! Conjugate Gradient scalars CGRELAX.128
& asor, CGRELAX.129
& oapr, CGRELAX.130
& apr2, CGRELAX.131
& apr4 CGRELAX.132
CGRELAX.133
C Flags used: (Pulled in from an include deck or whatever) CGRELAX.134
C L_OTIMER - Ocean Timer CGRELAX.135
C L_OCYCLIC - Ocean Cyclic CGRELAX.136
C L_OISLANDS - Ocean Islands CGRELAX.137
C L_OROTATE - Ocean Rotation CGRELAX.138
C L_OSYMM - Ocean Symmetry CGRELAX.139
C MIX - 1/0 its a mixing timestep CGRELAX.140
CGRELAX.141
CGRELAX.142
C======================================================================= CGRELAX.143
IF (L_OTIMER) CALL TIMER
('CGRELAX ',3) CGRELAX.144
CGRELAX.145
C Begin introductory section to prepare for the relaxation: CGRELAX.146
CGRELAX.147
C Initialize the work area: CGRELAX.148
DO J=J_1,J_JMT ORH5F402.5
DO I=1,IMT CGRELAX.150
CFN(I,J)=0.0 CGRELAX.151
CFS(I,J)=0.0 CGRELAX.152
CFE(I,J)=0.0 CGRELAX.153
CFW(I,J)=0.0 CGRELAX.154
CPF(I,J)=0.0 CGRELAX.155
ASUM(J)=0.0 ORH5F402.198
IF( L_OISLANDS ) THEN CGRELAX.156
COF(I,J)=1.0 CGRELAX.157
ISMASK(I,J)=0 CGRELAX.158
ENDIF CGRELAX.159
ENDDO CGRELAX.160
ENDDO CGRELAX.161
CGRELAX.162
IF (L_OISLANDS) THEN CGRELAX.163
C Form island mask: (ISMASK=0 over interior ocean points CGRELAX.164
C ISMASK=1 over perimeter ocean points CGRELAX.165
C ISMASK=2 over land points) CGRELAX.166
DO I=2,IMU CGRELAX.167
DO J=J_2,J_JMTM1 ORH5F402.6
TEST1=HR(I,J)*HR(I-1,J)*HR(I,J-1)*HR(I-1,J-1) CGRELAX.169
TEST2=HR(I,J)+HR(I-1,J)+HR(I,J-1)+HR(I-1,J-1) CGRELAX.170
IF(TEST1.EQ.0.0) ISMASK(I,J)=1 CGRELAX.171
IF(TEST2.EQ.0.0) ISMASK(I,J)=2 CGRELAX.172
ENDDO CGRELAX.173
ENDDO CGRELAX.174
CGRELAX.175
ENDIF CGRELAX.176
CGRELAX.177
C Calculate depth field from its reciprocal: CGRELAX.178
C Compute reciprocals with an epsilon added to avoid zero divide: CGRELAX.179
C (never mind the fact that it might be wrong!) CGRELAX.180
DO J=J_2,J_JMTM1 ORH5F402.7
DO I=1,IMT CGRELAX.182
H(I,J)=1.0/(HR(I,J)+1.E-20) CGRELAX.183
ENDDO CGRELAX.184
ENDDO CGRELAX.185
CGRELAX.186
IF (L_OISLANDS) THEN ! reset H over land to zero: CGRELAX.187
DO J=J_1,J_JMT ORH5F402.8
DO I=1,IMT CGRELAX.189
IF( HR(I,J) .EQ. 0.0) H(I,J)=0.0 CGRELAX.190
ENDDO CGRELAX.191
ENDDO CGRELAX.192
ENDIF CGRELAX.193
CGRELAX.194
IF( L_OCYCLIC )THEN ! set cyclic boundary conditions on H: CGRELAX.195
DO J=J_1,J_JMT ORH5F402.9
H(1,J)=H(IMUM1,J) CGRELAX.197
ENDDO CGRELAX.198
ENDIF CGRELAX.199
CGRELAX.200
*IF DEF,MPP ORH5F402.10
! Populate halo regions for H ORH5F402.11
CALL SWAPBOUNDS
(H,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.12
*ENDIF ORH5F402.13
C Generate arrays of coefficients for relaxation: CGRELAX.201
C CGRELAX.202
C 1st, compute coefficients of the Laplacian star: CGRELAX.203
C (hold non-interior points to zero using start and end indices) CGRELAX.204
DO 130 J=J_3,J_JMTM1 ORH5F402.14
DO 130 L=1,LSEG CGRELAX.206
IS=ISZ(J,L) CGRELAX.207
IF(IS.EQ.0) GO TO 130 CGRELAX.208
IE=IEZ(J,L) CGRELAX.209
FXA=2.0*CSTR(J)*CSTR(J) CGRELAX.210
FXB=2.0*CS(J )*CSTR(J)*DYTR(J)*DYUR(J ) CGRELAX.211
FXC=2.0*CS(J-1)*CSTR(J)*DYTR(J)*DYUR(J-1) CGRELAX.212
FX=1.0 CGRELAX.213
DO I=IS,IE CGRELAX.214
CFN(I,J)=FXB/(H(I-1,J)+H(I,J)) CGRELAX.215
CFS(I,J)=FXC/(H(I-1,J-1)+H(I,J-1)) CGRELAX.216
CFE(I,J)=FXA*DXUR(I)*DXTR(I)/(H(I,J)+H(I,J-1)) CGRELAX.217
CFW(I,J)=FXA*DXUR(I-1)*DXTR(I)/(H(I-1,J)+H(I-1,J-1)) CGRELAX.218
CPF(I,J)=FX/(CFN(I,J)+CFS(I,J)+CFE(I,J)+CFW(I,J)) CGRELAX.219
ENDDO CGRELAX.220
CGRELAX.221
C 2nd, augment coefficients for implicit treatment of Coriolis term: CGRELAX.222
IF(ACOR .NE. 0.0) THEN CGRELAX.223
CGRELAX.224
IF (L_OROTATE) THEN CGRELAX.225
FX=-0.5*C2DTSF*ACOR*CSTR(J)*DYTR(J) CGRELAX.226
DO I=IS,IE CGRELAX.227
CFN(I,J)=CFN(I,J) CGRELAX.228
& +(HR(I,J)*CORIOLIS(I,J)-HR(I-1,J)*CORIOLIS(I-1,J)) CGRELAX.229
& *FX*DXTR(I) CGRELAX.230
CFS(I,J)=CFS(I,J) CGRELAX.231
& -(HR(I,J-1)*CORIOLIS(I,J-1)-HR(I-1,J-1)*CORIOLIS(I-1,J-1)) CGRELAX.232
& *FX*DXTR(I) CGRELAX.233
CFE(I,J)=CFE(I,J) CGRELAX.234
& -(HR(I,J)*CORIOLIS(I,J)-HR(I,J-1)*CORIOLIS(I,J-1)) CGRELAX.235
& *FX*DXTR(I) CGRELAX.236
CFW(I,J)=CFW(I,J) CGRELAX.237
& +(HR(I-1,J)*CORIOLIS(I-1,J)-HR(I-1,J-1)*CORIOLIS(I-1,J-1)) CGRELAX.238
& *FX*DXTR(I) CGRELAX.239
ENDDO ! over I CGRELAX.240
ELSE CGRELAX.241
FX=-C2DTSF*ACOR*CSTR(J)*DYTR(J)*OMEGA CGRELAX.242
DO I=IS,IE CGRELAX.243
CGRELAX.244
CFN(I,J)=CFN(I,J)+(HR(I,J )-HR(I-1,J ))*SINE(J ) CGRELAX.245
& *FX*DXTR(I) CGRELAX.246
CFS(I,J)=CFS(I,J)-(HR(I,J-1)-HR(I-1,J-1))*SINE(J-1) CGRELAX.247
& *FX*DXTR(I) CGRELAX.248
CFE(I,J)=CFE(I,J)-(HR(I ,J)*SINE(J)-HR(I ,J-1)*SINE(J-1)) CGRELAX.249
& *FX*DXTR(I) CGRELAX.250
CFW(I,J)=CFW(I,J)+(HR(I-1,J)*SINE(J)-HR(I-1,J-1)*SINE(J-1)) CGRELAX.251
& *FX*DXTR(I) CGRELAX.252
ENDDO ! over I CGRELAX.253
ENDIF ! L_OROTATE = false CGRELAX.254
CGRELAX.255
ENDIF CGRELAX.256
CGRELAX.257
C 3rd, normalize coefficients and forcing term for efficiency: CGRELAX.258
DO I=IS,IE CGRELAX.259
CFN(I,J)=CFN(I,J)*CPF(I,J) CGRELAX.260
CFS(I,J)=CFS(I,J)*CPF(I,J) CGRELAX.261
CFE(I,J)=CFE(I,J)*CPF(I,J) CGRELAX.262
CFW(I,J)=CFW(I,J)*CPF(I,J) CGRELAX.263
ENDDO CGRELAX.264
130 CONTINUE ! end of J and L loops CGRELAX.265
IF (L_OISLANDS) THEN CGRELAX.266
CGRELAX.267
C 4th, compute coefficients on island perimeter points: CGRELAX.268
DO 180 ISLE=1,NISLE CGRELAX.269
DO J=J_1,J_JMT ORH5F402.199
COFIS_ROW(J)=0.0 ORH5F402.200
ENDDO ORH5F402.201
COFIS(ISLE)=0.0 CGRELAX.270
NSEG=ISEG(ISLE) CGRELAX.271
DO 175 N=1,NSEG CGRELAX.272
IS=ISIS(ISLE,N) CGRELAX.273
IE=IEIS(ISLE,N) CGRELAX.274
JS=JSIS(ISLE,N) CGRELAX.275
JE=JEIS(ISLE,N) CGRELAX.276
*IF DEF,MPP ORH5F402.15
c Adjust J indices to be relative to local values for each PE ORH5F402.16
IF ((JST.GT.JE).OR.(JFIN.LT.JS)) THEN ORH5F402.17
c Make sure the J loop doesn't get executed ORH5F402.18
JS = 1 ORH5F402.19
JE = 0 ORH5F402.20
ELSE ORH5F402.21
IF (JST.GT.JS) THEN ORH5F402.22
JS = JST ORH5F402.23
ENDIF ORH5F402.24
IF (JFIN.LT.JE) THEN ORH5F402.25
JE = JFIN ORH5F402.26
ENDIF ORH5F402.27
c Adjust to local versions of indices. ORH5F402.28
JS = JS - J_OFFSET ORH5F402.29
JE = JE - J_OFFSET ORH5F402.30
ENDIF ORH5F402.31
*ENDIF ORH5F402.32
DO 175 J=JS,JE CGRELAX.277
FXA=2.0*CSTR(J)*CSTR(J) CGRELAX.278
FXB=2.0*CS(J )*DYUR(J )*DYTR(J)*CSTR(J) CGRELAX.279
FXC=2.0*CS(J-1)*DYUR(J-1)*DYTR(J)*CSTR(J) CGRELAX.280
IF (L_OROTATE) THEN CGRELAX.281
FXD=-0.5*C2DTSF*ACOR*CSTR(J)*DYTR(J) CGRELAX.282
ELSE CGRELAX.283
FXD=-C2DTSF*ACOR*CSTR(J)*DYTR(J)*OMEGA CGRELAX.284
ENDIF CGRELAX.285
CGRELAX.286
DO 175 I=IS,IE CGRELAX.287
IF(ISMASK(I,J).NE.1) GO TO 174 CGRELAX.288
CGRELAX.289
IF (L_OROTATE) THEN CGRELAX.290
CGRELAX.291
IF(HR(I-1,J ).NE.0.0 .OR. HR(I ,J ).NE.0.0) CGRELAX.292
& CFN(I,J)=FXB/(H(I-1,J)+H(I,J)) CGRELAX.293
CGRELAX.294
IF(HR(I-1,J-1).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.295
& CFS(I,J)=FXC/(H(I-1,J-1)+H(I,J-1)) CGRELAX.296
CGRELAX.297
IF(HR(I ,J ).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.298
& CFE(I,J)=FXA*DXTR(I)*DXUR(I)/(H(I,J)+H(I,J-1)) CGRELAX.299
CGRELAX.300
IF(HR(I-1,J ).NE.0.0 .OR. HR(I-1,J-1).NE.0.0) CGRELAX.301
& CFW(I,J)=FXA*DXTR(I)*DXUR(I-1)/(H(I-1,J)+H(I-1,J-1)) CGRELAX.302
ELSE CGRELAX.303
CGRELAX.304
IF(HR(I-1,J ).NE.0.0 .OR. HR(I ,J ).NE.0.0) CGRELAX.305
& CFN(I,J)=FXB/(H(I-1,J)+H(I,J)) CGRELAX.306
CGRELAX.307
IF(HR(I-1,J-1).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.308
& CFS(I,J)=FXC/(H(I-1,J-1)+H(I,J-1)) CGRELAX.309
CGRELAX.310
IF(HR(I ,J ).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.311
& CFE(I,J)=FXA*DXTR(I)*DXUR(I)/(H(I,J)+H(I,J-1)) CGRELAX.312
CGRELAX.313
IF(HR(I-1,J ).NE.0.0 .OR. HR(I-1,J-1).NE.0.0) CGRELAX.314
& CFW(I,J)=FXA*DXTR(I)*DXUR(I-1)/(H(I-1,J)+H(I-1,J-1)) CGRELAX.315
ENDIF CGRELAX.316
ORH5F402.202
CPF(I,J) = 1.0/(CFN(i,j)+CFS(I,J)+CFE(I,J)+CFW(I,J)) CGRELAX.318
CGRELAX.319
IF (L_OROTATE) THEN CGRELAX.320
CGRELAX.321
IF(HR(I-1,J ).NE.0.0 .OR. HR(I ,J ).NE.0.0) CGRELAX.322
& CFN(I,J)=FXB/(H(I-1,J)+H(I,J)) CGRELAX.323
& +FXD*DXTR(I)*(HR(I,J)*CORIOLIS(I,J) CGRELAX.324
& -HR(I-1,J)*CORIOLIS(I-1,J)) CGRELAX.325
CGRELAX.326
IF(HR(I-1,J-1).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.327
& CFS(I,J)=FXC/(H(I-1,J-1)+H(I,J-1)) CGRELAX.328
& -FXD*DXTR(I)*(HR(I,J-1)*CORIOLIS(I,J-1) CGRELAX.329
& -HR(I-1,J-1)*CORIOLIS(I-1,J-1)) CGRELAX.330
CGRELAX.331
IF(HR(I ,J ).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.332
& CFE(I,J)=FXA*DXTR(I)*DXUR(I)/(H(I,J)+H(I,J-1)) CGRELAX.333
& -FXD*DXTR(I)*(HR(I,J)*CORIOLIS(I,J) CGRELAX.334
& -HR(I,J-1)*CORIOLIS(I,J-1)) CGRELAX.335
CGRELAX.336
IF(HR(I-1,J ).NE.0.0 .OR. HR(I-1,J-1).NE.0.0) CGRELAX.337
& CFW(I,J)=FXA*DXTR(I)*DXUR(I-1)/(H(I-1,J)+H(I-1,J-1)) CGRELAX.338
& +FXD*DXTR(I)*(HR(I-1,J)*CORIOLIS(I-1,J) CGRELAX.339
& -HR(I-1,J-1)*CORIOLIS(I-1,J-1)) CGRELAX.340
ELSE CGRELAX.341
CGRELAX.342
IF(HR(I-1,J ).NE.0.0 .OR. HR(I ,J ).NE.0.0) CGRELAX.343
& CFN(I,J)=FXB/(H(I-1,J)+H(I,J)) CGRELAX.344
& +FXD*DXTR(I)*(HR(I,J)-HR(I-1,J))*SINE(J) CGRELAX.345
CGRELAX.346
IF(HR(I-1,J-1).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.347
& CFS(I,J)=FXC/(H(I-1,J-1)+H(I,J-1)) CGRELAX.348
& -FXD*DXTR(I)*(HR(I,J-1)-HR(I-1,J-1))*SINE(J-1) CGRELAX.349
CGRELAX.350
IF(HR(I ,J ).NE.0.0 .OR. HR(I ,J-1).NE.0.0) CGRELAX.351
& CFE(I,J)=FXA*DXTR(I)*DXUR(I)/(H(I,J)+H(I,J-1)) CGRELAX.352
& -FXD*DXTR(I)*(HR(I,J)*SINE(J)-HR(I,J-1)*SINE(J-1)) CGRELAX.353
CGRELAX.354
IF(HR(I-1,J ).NE.0.0 .OR. HR(I-1,J-1).NE.0.0) CGRELAX.355
& CFW(I,J)=FXA*DXTR(I)*DXUR(I-1)/(H(I-1,J)+H(I-1,J-1)) CGRELAX.356
& +FXD*DXTR(I)* CGRELAX.357
& (HR(I-1,J)*SINE(J)-HR(I-1,J-1)*SINE(J-1)) CGRELAX.358
ENDIF CGRELAX.359
CGRELAX.360
CGRELAX.361
CFN(I,J)=CFN(I,J)*CPF(I,J) CGRELAX.362
CFS(I,J)=CFS(I,J)*CPF(I,J) CGRELAX.363
CFE(I,J)=CFE(I,J)*CPF(I,J) CGRELAX.364
CFW(I,J)=CFW(I,J)*CPF(I,J) CGRELAX.365
COF(I,J)=CST(J)*DXT(I)*DYT(J)/CPF(I,J) CGRELAX.366
COFIS_ROW(J)=COFIS_ROW(J)+COF(I,J) ORH5F402.203
174 CONTINUE ! jumped to by a goto above CGRELAX.368
175 CONTINUE ! end of N, J and I loops CGRELAX.369
ORH5F402.204
! Now we must add all COFIS values for this island ORH5F402.205
! in a manner which will allow bit comparison. ORH5F402.206
CALL CGSUMMATION
ORH5F402.207
& (COFIS_ROW,JMT_GLOBAL,J_1,J_JMT,JMT, ORH5F402.208
& JST,JFIN,O_MYPE,O_NPROC,COFIS(ISLE)) ORH5F402.209
COFIS(ISLE)=1.0/COFIS(ISLE) CGRELAX.370
ORH5F402.210
180 CONTINUE ! end of isle loop CGRELAX.371
ENDIF ! L_OISLANDS = true CGRELAX.372
CGRELAX.373
DO ISLE=1,NISLE CGRELAX.374
NSEG=ISEG(ISLE) CGRELAX.375
DO N=1,NSEG CGRELAX.376
IS=ISIS(ISLE,N) CGRELAX.377
IE=IEIS(ISLE,N) CGRELAX.378
JS=JSIS(ISLE,N) CGRELAX.379
JE=JEIS(ISLE,N) CGRELAX.380
*IF DEF,MPP ORH5F402.33
c Adjust J indices to be relative to local values for each PE ORH5F402.34
IF ((JST.GT.JE).OR.(JFIN.LT.JS)) THEN ORH5F402.35
c Make sure the J loop doesn't get executed ORH5F402.36
JS = 1 ORH5F402.37
JE = 0 ORH5F402.38
ELSE ORH5F402.39
IF (JST.GT.JS) THEN ORH5F402.40
JS = JST ORH5F402.41
ENDIF ORH5F402.42
IF (JFIN.LT.JE) THEN ORH5F402.43
JE = JFIN ORH5F402.44
ENDIF ORH5F402.45
c Adjust to local versions of indices. ORH5F402.46
JS = JS - J_OFFSET ORH5F402.47
JE = JE - J_OFFSET ORH5F402.48
ENDIF ORH5F402.49
*ENDIF ORH5F402.50
DO J=JS,JE CGRELAX.381
DO I=IS,IE CGRELAX.382
IF(ISMASK(I,J).EQ.1) THEN CGRELAX.383
CGRELAX.384
COF(I,J) = COF(I,J)*COFIS(ISLE) CGRELAX.385
ENDIF ORH5F402.211
ENDDO CGRELAX.387
ENDDO CGRELAX.388
ENDDO CGRELAX.389
ENDDO CGRELAX.390
CGRELAX.391
IF (L_OCYCLIC) THEN CGRELAX.392
DO J=J_1,J_JMT ORH5F402.51
COF(1,j) = 0.0 CGRELAX.394
COF(IMT,J) = 0.0 CGRELAX.395
ENDDO CGRELAX.396
ENDIF CGRELAX.397
CGRELAX.398
DO J=J_1,J_JMT ORH5F402.52
DO I = 1, IMT CGRELAX.400
ZTD(I,J)=ZTD(I,J)*CPF(I,J) CGRELAX.401
ENDDO CGRELAX.402
ENDDO CGRELAX.403
C Compute a first guess for the relaxation by extrapolating the two CGRELAX.404
C previous solutions forward in time: CGRELAX.405
C 1st, save values in ptd in array res: CGRELAX.406
C 2nd, perform time extrapolation (accounting for mixing timestep): CGRELAX.407
C 3rd, determine max ptd over all points and use this CGRELAX.408
C to compute criterion for convergence: CGRELAX.409
C 4th, now copy original values from ptd (now in res) into PTDB: CGRELAX.410
C 5th, set res and gdir to zero prior to using them in cg context: CGRELAX.411
CRTP = 0.0 CGRELAX.412
FXA=1.0 CGRELAX.413
FXB=2.0 CGRELAX.414
IF(MIX .NE. 0) FXA=0.5 CGRELAX.415
DO J=J_1,J_JMT ORH5F402.53
DO I=1,IMT CGRELAX.417
res(I,J)=PTD(I,J) CGRELAX.418
PTD(I,J)=FXA * (FXB*PTD(I,J)-PTDB(I,J)) CGRELAX.419
CRTP = MAX(ABS(PTD(I,J)),CRTP) CGRELAX.420
PTDB(I,J)=res(I,J) CGRELAX.421
RES(I,J)=0.0 CGRELAX.422
GDIR(I,J)=0.0 CGRELAX.423
ENDDO CGRELAX.424
ENDDO CGRELAX.425
*IF DEF,MPP ORH5F402.166
CALL GC_RMAX (
1,O_NPROC,INFO,CRTP) ORH5F402.167
*ENDIF ORH5F402.168
CRTP=CRTP*CRIT CGRELAX.426
IF (CRTP.LE.0.0) CRTP=1.0 ! covers new runs when ptd is zero CGRELAX.427
CGRELAX.428
CGRELAX.429
C This is the `stop when ||r|| < stop_tol x ||b||' criterion CGRELAX.430
C where stop_tol is passed in from CRIT, and the inf-norms are used CGRELAX.431
CGRELAX.432
beta = 0.0 CGRELAX.433
MSCAN=0 CGRELAX.434
CGRELAX.435
*IF DEF,MPP ORH5F402.172
CALL SWAPBOUNDS
(PTD,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.173
*ENDIF ORH5F402.174
C compute initial residuals: CGRELAX.436
DO J=J_2,J_JMTM1 ORH5F402.54
do i=2,imtm1 CGRELAX.438
res(i,j) = cfn(i,j)*ptd(i,j+1) + CGRELAX.439
& cfs(i,j)*ptd(i,j-1) + CGRELAX.440
& cfe(i,j)*ptd(i+1,j) + CGRELAX.441
& cfw(i,j)*ptd(i-1,j) - CGRELAX.442
& ptd(i,j) - ztd(i,j) CGRELAX.443
if( L_OISLANDS ) res(i,j) = res(i,j)*cof(i,j) CGRELAX.444
enddo CGRELAX.445
enddo CGRELAX.446
CGRELAX.447
CGRELAX.448
C Find initial island residual using a line integral: CGRELAX.449
if( L_OISLANDS) then CGRELAX.450
DO ISLE=1,NISLE CGRELAX.451
DO J=J_1,J_JMT ORH5F402.212
RESIS_ROW(J)=0.0 ORH5F402.213
ENDDO ORH5F402.214
RESIS=0.0 CGRELAX.452
NSEG=ISEG(ISLE) CGRELAX.453
DO N=1,NSEG CGRELAX.454
IS=ISIS(ISLE,N) CGRELAX.455
IE=IEIS(ISLE,N) CGRELAX.456
JS=JSIS(ISLE,N) CGRELAX.457
JE=JEIS(ISLE,N) CGRELAX.458
*IF DEF,MPP ORH5F402.55
c Adjust J indices to be relative to local values for each PE ORH5F402.56
IF ((JST.GT.JE).OR.(JFIN.LT.JS)) THEN ORH5F402.57
c Make sure the J loop doesn't get executed ORH5F402.58
JS = 1 ORH5F402.59
JE = 0 ORH5F402.60
ELSE ORH5F402.61
IF (JST.GT.JS) THEN ORH5F402.62
JS = JST ORH5F402.63
ENDIF ORH5F402.64
IF (JFIN.LT.JE) THEN ORH5F402.65
JE = JFIN ORH5F402.66
ENDIF ORH5F402.67
c Adjust to local versions of indices. ORH5F402.68
JS = JS - J_OFFSET ORH5F402.69
JE = JE - J_OFFSET ORH5F402.70
ENDIF ORH5F402.71
*ENDIF ORH5F402.72
DO J=JS,JE CGRELAX.459
DO I=IS,IE CGRELAX.460
IF(ISMASK(I,J).EQ.1) THEN CGRELAX.461
resis_ROW(J) = resis_ROW(J) + res(i,j) ORH5F402.215
ENDIF CGRELAX.463
ENDDO ! over I CGRELAX.464
ENDDO ! over J CGRELAX.465
ENDDO CGRELAX.466
ORH5F402.216
CALL CGSUMMATION
ORH5F402.217
& (RESIS_ROW,JMT_GLOBAL,J_1,J_JMT,JMT, ORH5F402.218
& JST,JFIN,O_MYPE,O_NPROC,RESIS) ORH5F402.219
ORH5F402.220
DO N=1,NSEG CGRELAX.467
IS=ISIS(ISLE,N) CGRELAX.468
IE=IEIS(ISLE,N) CGRELAX.469
JS=JSIS(ISLE,N) CGRELAX.470
JE=JEIS(ISLE,N) CGRELAX.471
*IF DEF,MPP ORH5F402.73
c Adjust J indices to be relative to local values for each PE ORH5F402.74
IF ((JST.GT.JE).OR.(JFIN.LT.JS)) THEN ORH5F402.75
c Make sure the J loop doesn't get executed ORH5F402.76
JS = 1 ORH5F402.77
JE = 0 ORH5F402.78
ELSE ORH5F402.79
IF (JST.GT.JS) THEN ORH5F402.80
JS = JST ORH5F402.81
ENDIF ORH5F402.82
IF (JFIN.LT.JE) THEN ORH5F402.83
JE = JFIN ORH5F402.84
ENDIF ORH5F402.85
c Adjust to local versions of indices. ORH5F402.86
JS = JS - J_OFFSET ORH5F402.87
JE = JE - J_OFFSET ORH5F402.88
ENDIF ORH5F402.89
*ENDIF ORH5F402.90
DO J=JS,JE CGRELAX.472
DO I=IS,IE CGRELAX.473
IF(ISMASK(I,J).EQ.1) THEN CGRELAX.474
res(i,j) = resis CGRELAX.475
ENDIF CGRELAX.476
ENDDO ! over I CGRELAX.477
ENDDO ! over J CGRELAX.478
ENDDO CGRELAX.479
ENDDO CGRELAX.480
endif CGRELAX.481
if( L_OCYCLIC) then ! set cyclic bc CGRELAX.482
DO J=J_2,J_JMTM1 ORH5F402.91
res(1,j) = res(imtm1,j) CGRELAX.484
res(imt,j) = res(2,j) CGRELAX.485
enddo CGRELAX.486
endif CGRELAX.487
*IF DEF,MPP ORH5F402.175
CALL SWAPBOUNDS
(RES,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.176
*ENDIF ORH5F402.177
if( L_OSYMM) then ! set symmetry bc CGRELAX.488
do i=1,imt CGRELAX.489
*IF DEF,MPP ORH5F402.138
IF (JST.LE.JMT_GLOBAL.AND.JFIN.GE.JMT_GLOBAL) THEN ORH5F402.139
*ENDIF ORH5F402.140
res(i,j_jmt) = - res(i,j_jmtm1) ORH5F402.141
*IF DEF,MPP ORH5F402.142
ENDIF ORH5F402.143
*ENDIF ORH5F402.144
enddo CGRELAX.491
endif CGRELAX.492
CGRELAX.493
CGRELAX.494
C End introductory section. CGRELAX.495
C======================================================================= CGRELAX.496
CGRELAX.497
C Begin the relaxation: CGRELAX.498
300 CONTINUE CGRELAX.499
MSCAN=MSCAN+1 ! MSCAN will therefore be 1 on first scan. CGRELAX.500
CGRELAX.501
*IF DEF,MPP ORH5F402.178
CALL SWAPBOUNDS
(RES,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.179
*ENDIF ORH5F402.180
DO J=J_2,J_JMTM1 ORH5F402.92
do i=2,imtm1 CGRELAX.503
gdir(i,j) = cfn(i,j) * res(i,j+1) + CGRELAX.504
& cfs(i,j) * res(i,j-1) + CGRELAX.505
& cfe(i,j) * res(i+1,j) + CGRELAX.506
& cfw(i,j) * res(i-1,j) - CGRELAX.507
& res(i,j) CGRELAX.508
if( L_OISLANDS) then CGRELAX.509
gdir(i,j) = gdir(i,j)*cof(i,j) CGRELAX.510
endif CGRELAX.511
enddo CGRELAX.512
enddo CGRELAX.513
CGRELAX.514
CGRELAX.515
C Find island residuals using a line integral: CGRELAX.516
C Also update gdir on perimeter & interior of island: CGRELAX.517
if( L_OISLANDS) then CGRELAX.518
CGRELAX.519
DO ISLE=1,NISLE CGRELAX.520
DO J = J_1,J_JMT ORH5F402.221
RESIS_ROW(J) = 0.0 ORH5F402.222
ENDDO ORH5F402.223
RESIS=0.0 CGRELAX.521
NSEG=ISEG(ISLE) CGRELAX.522
DO N=1,NSEG CGRELAX.523
IS=ISIS(ISLE,N) CGRELAX.524
IE=IEIS(ISLE,N) CGRELAX.525
JS=JSIS(ISLE,N) CGRELAX.526
JE=JEIS(ISLE,N) CGRELAX.527
*IF DEF,MPP ORH5F402.93
c Adjust J indices to be relative to local values for each PE ORH5F402.94
IF ((JST.GT.JE).OR.(JFIN.LT.JS)) THEN ORH5F402.95
c Make sure the J loop doesn't get executed ORH5F402.96
JS = 1 ORH5F402.97
JE = 0 ORH5F402.98
ELSE ORH5F402.99
IF (JST.GT.JS) THEN ORH5F402.100
JS = JST ORH5F402.101
ENDIF ORH5F402.102
IF (JFIN.LT.JE) THEN ORH5F402.103
JE = JFIN ORH5F402.104
ENDIF ORH5F402.105
c Adjust to local versions of indices. ORH5F402.106
JS = JS - J_OFFSET ORH5F402.107
JE = JE - J_OFFSET ORH5F402.108
ENDIF ORH5F402.109
*ENDIF ORH5F402.110
DO J=JS,JE CGRELAX.528
DO I=IS,IE CGRELAX.529
IF(ISMASK(I,J).EQ.1) THEN CGRELAX.530
resis_ROW(J) = resis_ROW(J) + gdir(i,j) ORH5F402.224
ENDIF CGRELAX.532
ENDDO ! over I CGRELAX.533
ENDDO ! over J CGRELAX.534
ENDDO CGRELAX.535
ORH5F402.225
CALL CGSUMMATION
ORH5F402.226
& (RESIS_ROW,JMT_GLOBAL,J_1,J_JMT,JMT, ORH5F402.227
& JST,JFIN,O_MYPE,O_NPROC,RESIS) ORH5F402.228
ORH5F402.229
DO N=1,NSEG CGRELAX.536
IS=ISIS(ISLE,N) CGRELAX.537
IE=IEIS(ISLE,N) CGRELAX.538
JS=JSIS(ISLE,N) CGRELAX.539
JE=JEIS(ISLE,N) CGRELAX.540
*IF DEF,MPP ORH5F402.111
c Adjust J indices to be relative to local values for each PE ORH5F402.112
IF ((JST.GT.JE).OR.(JFIN.LT.JS)) THEN ORH5F402.113
c Make sure the J loop doesn't get executed ORH5F402.114
JS = 1 ORH5F402.115
JE = 0 ORH5F402.116
ELSE ORH5F402.117
IF (JST.GT.JS) THEN ORH5F402.118
JS = JST ORH5F402.119
ENDIF ORH5F402.120
IF (JFIN.LT.JE) THEN ORH5F402.121
JE = JFIN ORH5F402.122
ENDIF ORH5F402.123
c Adjust to local versions of indices. ORH5F402.124
JS = JS - J_OFFSET ORH5F402.125
JE = JE - J_OFFSET ORH5F402.126
ENDIF ORH5F402.127
*ENDIF ORH5F402.128
DO J=JS,JE CGRELAX.541
DO I=IS,IE CGRELAX.542
IF(ISMASK(I,J).EQ.1) THEN CGRELAX.543
gdir(i,j) = resis CGRELAX.544
ENDIF CGRELAX.545
ENDDO ! over I CGRELAX.546
ENDDO ! over J CGRELAX.547
ENDDO CGRELAX.548
ENDDO CGRELAX.549
endif CGRELAX.550
if( L_OCYCLIC) then CGRELAX.551
DO J=J_2,J_JMTM1 ORH5F402.129
gdir(1,j) = gdir(imtm1,j) CGRELAX.553
gdir(imt,j) = gdir(2,j) CGRELAX.554
enddo CGRELAX.555
endif CGRELAX.556
if( L_OSYMM) then ! set symmetry bc CGRELAX.557
*IF DEF,MPP ORH5F402.181
CALL SWAPBOUNDS
(GDIR,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.182
*ENDIF ORH5F402.183
do i=1,imt CGRELAX.558
*IF DEF,MPP ORH5F402.145
IF (JST.LE.JMT_GLOBAL.AND.JFIN.GE.JMT_GLOBAL) THEN ORH5F402.146
*ENDIF ORH5F402.147
gdir(i,j_jmt) = - gdir(i,j_jmtm1) ORH5F402.148
*IF DEF,MPP ORH5F402.149
ENDIF ORH5F402.150
*ENDIF ORH5F402.151
enddo CGRELAX.560
*IF DEF,MPP ORH5F402.184
CALL SWAPBOUNDS
(GDIR,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.185
*ENDIF ORH5F402.186
endif CGRELAX.561
C gdir now contains the preconditioned solution. CGRELAX.562
CGRELAX.563
C Compute dot product of res and gdir: CGRELAX.564
apr4 = 0.0 CGRELAX.565
DO J=J_2,J_JMTM1 ORH5F402.130
asum(j) = 0.0 CGRELAX.567
do i=2,imtm1 CGRELAX.568
asum(j) = asum(j) + gdir(i,j)*res(i,j) CGRELAX.569
enddo CGRELAX.570
enddo CGRELAX.572
ORH5F402.230
CALL CGSUMMATION
ORH5F402.231
& (asum,JMT_GLOBAL,J_1,J_JMT,JMT, ORH5F402.232
& JST,JFIN,O_MYPE,O_NPROC,apr4) ORH5F402.233
CGRELAX.573
CGRELAX.574
if (mscan .gt. 1) beta = apr4/oapr CGRELAX.575
oapr = apr4 CGRELAX.576
CGRELAX.577
C update search directions: CGRELAX.578
DO J=J_2,J_JMTM1 ORH5F402.131
do i=1,imt CGRELAX.580
hdir(i,j) = res(i,j) + beta*hdir(i,j) CGRELAX.581
fdir(i,j) = gdir(i,j) + beta*fdir(i,j) CGRELAX.582
enddo CGRELAX.583
enddo CGRELAX.584
CGRELAX.585
C apr2 is dot product of fdir with itself: CGRELAX.586
apr2 = 0.0 CGRELAX.587
DO J=J_2,J_JMTM1 ORH5F402.132
asum(j) = 0.0 CGRELAX.589
do i=2,imtm1 CGRELAX.590
asum(j) = asum(j) + fdir(i,j)**2 CGRELAX.591
enddo CGRELAX.592
enddo CGRELAX.594
CGRELAX.595
CALL CGSUMMATION
ORH5F402.234
& (asum,JMT_GLOBAL,J_1,J_JMT,JMT, ORH5F402.235
& JST,JFIN,O_MYPE,O_NPROC,apr2) ORH5F402.236
CGRELAX.596
C Calculate stepsize (asor) & make a correction to ptd res: CGRELAX.597
asor = - apr4/apr2 CGRELAX.598
CGRELAX.599
CGRELAX.600
DO J=J_2,J_JMTM1 ORH5F402.133
do i=1,imt CGRELAX.602
ptd(i,j) = ptd(i,j) + asor*hdir(i,j) CGRELAX.603
res(i,j) = res(i,j) + asor*fdir(i,j) CGRELAX.604
enddo CGRELAX.605
enddo CGRELAX.606
CGRELAX.607
if( L_OCYCLIC) then ! set cyclic condition CGRELAX.608
DO J=J_2,J_JMTM1 ORH5F402.134
res(1,j) = res(imtm1,j) CGRELAX.610
res(imt,j) = res(2,j) CGRELAX.611
enddo CGRELAX.612
endif CGRELAX.613
CGRELAX.614
C Find the maximum absolute residual to determine convergence: CGRELAX.615
resmax = 0.0 CGRELAX.616
DO J=J_3,jscan ORH5F402.135
do i=2,imtm1 CGRELAX.618
resmax = max(abs(res(i,j)), resmax) CGRELAX.619
enddo CGRELAX.620
enddo CGRELAX.621
*IF DEF,MPP ORH5F402.169
CALL GC_RMAX (
1,O_NPROC,INFO,resmax) ORH5F402.170
*ENDIF ORH5F402.171
if (L_OSYMM) then CGRELAX.622
*IF DEF,MPP ORH5F402.187
CALL SWAPBOUNDS
(RES,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.188
*ENDIF ORH5F402.189
do i=1,imt CGRELAX.623
*IF DEF,MPP ORH5F402.152
IF (JST.LE.JMT_GLOBAL.AND.JFIN.GE.JMT_GLOBAL) THEN ORH5F402.153
*ENDIF ORH5F402.154
res(i,j_jmt) = - res(i,j_jmtm1) ORH5F402.155
*IF DEF,MPP ORH5F402.156
ENDIF ORH5F402.157
*ENDIF ORH5F402.158
enddo CGRELAX.625
*IF DEF,MPP ORH5F402.190
CALL SWAPBOUNDS
(RES,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.191
*ENDIF ORH5F402.192
endif CGRELAX.626
CGRELAX.627
CGRELAX.628
CGRELAX.629
C Do another iteration unless the max residual < crtp or CGRELAX.630
C the number of scans reaches mxscan: CGRELAX.631
if (resmax .ge. crtp .and. mscan .lt. mxscan) go to 300 CGRELAX.632
C end of the iteration loop CGRELAX.633
CGRELAX.634
if (L_OSYMM) then ! set symmetry on northern wall CGRELAX.635
*IF DEF,MPP ORH5F402.193
CALL SWAPBOUNDS
(PTD,IMT,JMT,O_EW_HALO,O_NS_HALO,1) ORH5F402.194
*ENDIF ORH5F402.195
do i=1,imt CGRELAX.636
*IF DEF,MPP ORH5F402.159
IF (JST.LE.JMT_GLOBAL.AND.JFIN.GE.JMT_GLOBAL) THEN ORH5F402.160
*ENDIF ORH5F402.161
ptd(i,j_jmt) = - ptd(i,j_jmtm1) ORH5F402.162
*IF DEF,MPP ORH5F402.163
ENDIF ORH5F402.164
*ENDIF ORH5F402.165
enddo CGRELAX.638
endif CGRELAX.639
CGRELAX.640
C--------------------------------------------------------------------- CGRELAX.641
C Update the stream function based upon the relaxation solution: CGRELAX.642
C (Can use res as a work buffer as we are no longer interested in CGRELAX.643
C its contents for this call.) CGRELAX.644
DO J=J_1,J_JMT ORH5F402.136
DO I=1,IMT CGRELAX.646
res(i,j) = pb(i,j) + ptd(i,j) CGRELAX.647
pb(i,j) = p(i,j) CGRELAX.648
p(i,j) = res(i,j) CGRELAX.649
ENDDO CGRELAX.650
ENDDO CGRELAX.651
C so pb is old value, p is current value, ready for next call or dump CGRELAX.652
CGRELAX.653
C On a mixing timestep, alter PTD to be consistent with CGRELAX.654
C normal, leap-frog stepping: CGRELAX.655
IF( MIX .NE. 0 )THEN CGRELAX.656
DO J=J_1,J_JMT ORH5F402.137
DO I=1,IMT CGRELAX.658
PTD(I,J)=2.0*PTD(I,J) CGRELAX.659
ENDDO CGRELAX.660
ENDDO CGRELAX.661
ENDIF CGRELAX.662
CGRELAX.663
CGRELAX.664
IF (L_OTIMER) CALL TIMER
('CGRELAX ',4) CGRELAX.665
CGRELAX.666
RETURN CGRELAX.667
END CGRELAX.668
*ENDIF CGRELAX.669