File indexing completed on 2024-09-20 05:10:17 UTC
view on githubraw file Latest commit e6e223b2 on 2024-09-19 22:01:15 UTC
015c19607c Jean*0001 #include "CPP_OPTIONS.h"
0002 #ifdef TARGET_NEC_SX
0003
0004
0005 #ifndef CG3D_OUTERLOOPITERS
0006 # define CG3D_OUTERLOOPITERS 10
0007 #endif
0008 #endif /* TARGET_NEC_SX */
0009
0010
0011
0012
0013 SUBROUTINE CG3D_EX0(
0014 U cg3d_b, cg3d_x,
0015 O firstResidual, lastResidual,
0016 U numIters,
0017 I myIter, myThid )
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 IMPLICIT NONE
0037
0038 #include "SIZE.h"
0039 #include "EEPARAMS.h"
e6e223b277 Jean*0040 #ifdef ALLOW_NONHYDROSTATIC
0041 # include "PARAMS.h"
0042 # include "GRID.h"
0043 # include "SURFACE.h"
0044 # include "CG3D.h"
0045 #endif /* ALLOW_NONHYDROSTATIC */
015c19607c Jean*0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 _RL cg3d_b(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy)
0060 _RL cg3d_x(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy)
0061 _RL firstResidual
0062 _RL lastResidual
0063 INTEGER numIters
0064 INTEGER myIter
0065 INTEGER myThid
0066
0067 #ifdef ALLOW_NONHYDROSTATIC
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 INTEGER bi, bj
0084 INTEGER i, j, k, it3d
0085 INTEGER actualIts(nSx,nSy)
0086 INTEGER km1, kp1
0087 _RL maskM1, maskP1
0088 _RL err_sq, errTile(nSx,nSy)
0089 _RL eta_qrNtile(nSx,nSy)
0090 _RL eta_qrNM1(nSx,nSy)
0091 _RL cgBeta
0092 _RL alpha , alphaTile(nSx,nSy)
0093 _RL sumRHS, sumRHStile(nSx,nSy)
0094 _RL rhsMax, rhsMaxLoc
0095 _RL rhsNorm(nSx,nSy)
0096 CHARACTER*(MAX_LEN_MBUF) msgBuf
0097 LOGICAL printResidual
0098 _RL surfFac
0099 #ifdef NONLIN_FRSURF
0100 INTEGER ks
0101 _RL surfTerm(sNx,sNy)
0102 #endif /* NONLIN_FRSURF */
0103
0104
0105
0106 IF ( select_rStar .NE. 0 ) THEN
0107 surfFac = freeSurfFac
0108 ELSE
0109 surfFac = 0.
0110 ENDIF
0111 #ifdef NONLIN_FRSURF
0112 DO j=1,sNy
0113 DO i=1,sNx
0114 surfTerm(i,j) = 0.
0115 ENDDO
0116 ENDDO
0117 #endif /* NONLIN_FRSURF */
0118
0119
0120 rhsMax = 0. _d 0
0121 DO bj=myByLo(myThid),myByHi(myThid)
0122 DO bi=myBxLo(myThid),myBxHi(myThid)
0123
0124 actualIts(bi,bj) = 0
0125 eta_qrNM1(bi,bj) = 1. _d 0
0126 rhsMaxLoc = 0. _d 0
0127 DO k=1,Nr
0128 DO j=1,sNy
0129 DO i=1,sNx
0130 cg3d_b(i,j,k,bi,bj) = cg3d_b(i,j,k,bi,bj)*cg3dNorm
0131 & * maskC(i,j,k,bi,bj)
0132 rhsMaxLoc = MAX(ABS(cg3d_b(i,j,k,bi,bj)),rhsMaxLoc)
0133 ENDDO
0134 ENDDO
0135 ENDDO
0136 rhsNorm(bi,bj) = 1. _d 0
0137 IF ( rhsMaxLoc .NE. 0. ) rhsNorm(bi,bj) = 1. _d 0 / rhsMaxLoc
0138 DO k=1,Nr
0139 DO j=1,sNy
0140 DO i=1,sNx
0141 cg3d_b(i,j,k,bi,bj) = cg3d_b(i,j,k,bi,bj)*rhsNorm(bi,bj)
0142 cg3d_x(i,j,k,bi,bj) = cg3d_x(i,j,k,bi,bj)*rhsNorm(bi,bj)
0143 ENDDO
0144 ENDDO
0145 ENDDO
0146 rhsMax = MAX( rhsMaxLoc, rhsMax )
0147
0148 ENDDO
0149 ENDDO
0150 _GLOBAL_MAX_RL( rhsMax, myThid )
0151
0152
0153 _EXCH_XYZ_RL( cg3d_x, myThid )
0154
0155
0156 err_sq = 0.
0157 sumRHS = 0.
0158 DO bj=myByLo(myThid),myByHi(myThid)
0159 DO bi=myBxLo(myThid),myBxHi(myThid)
0160 errTile(bi,bj) = 0. _d 0
0161 sumRHStile(bi,bj) = 0. _d 0
0162 #ifdef NONLIN_FRSURF
0163 IF ( select_rStar .NE. 0 ) THEN
0164 DO j=1,sNy
0165 DO i=1,sNx
0166 surfTerm(i,j) = 0.
0167 ENDDO
0168 ENDDO
0169 DO k=1,Nr
0170 DO j=1,sNy
0171 DO i=1,sNx
0172 surfTerm(i,j) = surfTerm(i,j)
0173 & +cg3d_x(i,j,k,bi,bj)*drF(k)*h0FacC(i,j,k,bi,bj)
0174 ENDDO
0175 ENDDO
0176 ENDDO
0177 DO j=1,sNy
0178 DO i=1,sNx
0179 ks = kSurfC(i,j,bi,bj)
0180 surfTerm(i,j) = surfTerm(i,j)*cg3dNorm
0181 & *recip_Rcol(i,j,bi,bj)*recip_Rcol(i,j,bi,bj)
0182 & *rA(i,j,bi,bj)*deepFac2F(ks)
e6e223b277 Jean*0183 & *recip_Bo(i,j,bi,bj)/deltaTMom/deltaTFreeSurf
015c19607c Jean*0184 ENDDO
0185 ENDDO
0186 ENDIF
0187 #endif /* NONLIN_FRSURF */
0188 DO k=1,Nr
0189 km1 = MAX(k-1, 1 )
0190 kp1 = MIN(k+1, Nr)
0191 maskM1 = 1. _d 0
0192 maskP1 = 1. _d 0
0193 IF ( k .EQ. 1 ) maskM1 = 0. _d 0
0194 IF ( k .EQ. Nr) maskP1 = 0. _d 0
0195 #ifdef TARGET_NEC_SX
0196
0197 #endif /* TARGET_NEC_SX */
0198 DO j=1,sNy
0199 DO i=1,sNx
0200 cg3d_r(i,j,k,bi,bj) = cg3d_b(i,j,k,bi,bj)
0201 & -( 0.
0202 & +aW3d( i, j, k, bi,bj)*cg3d_x(i-1,j, k, bi,bj)
0203 & +aW3d(i+1,j, k, bi,bj)*cg3d_x(i+1,j, k, bi,bj)
0204 & +aS3d( i, j, k, bi,bj)*cg3d_x( i,j-1,k, bi,bj)
0205 & +aS3d( i,j+1,k, bi,bj)*cg3d_x( i,j+1,k, bi,bj)
0206 & +aV3d( i, j, k, bi,bj)*cg3d_x( i, j,km1,bi,bj)*maskM1
0207 & +aV3d( i, j,kp1,bi,bj)*cg3d_x( i, j,kp1,bi,bj)*maskP1
0208 & +aC3d( i, j, k, bi,bj)*cg3d_x( i, j, k, bi,bj)
0209 #ifdef NONLIN_FRSURF
0210 & -surfFac*surfTerm(i,j)*drF(k)*h0FacC(i,j,k,bi,bj)
0211 #endif /* NONLIN_FRSURF */
0212 & )
0213 errTile(bi,bj) = errTile(bi,bj)
0214 & +cg3d_r(i,j,k,bi,bj)*cg3d_r(i,j,k,bi,bj)
0215 sumRHStile(bi,bj) = sumRHStile(bi,bj)+cg3d_b(i,j,k,bi,bj)
0216 ENDDO
0217 ENDDO
0218 DO j=0,sNy+1
0219 DO i=0,sNx+1
0220 cg3d_s(i,j,k,bi,bj) = 0.
0221 ENDDO
0222 ENDDO
0223 ENDDO
0224 err_sq = MAX( errTile(bi,bj), err_sq )
0225 sumRHS = MAX( ABS(sumRHStile(bi,bj)), sumRHS )
0226 ENDDO
0227 ENDDO
0228 CALL EXCH_S3D_RL( cg3d_r, Nr, myThid )
0229 _GLOBAL_MAX_RL( err_sq, myThid )
0230 _GLOBAL_MAX_RL( sumRHS, myThid )
0231 IF ( debugLevel.GE.debLevC .AND. diagFreq.GT.0. ) THEN
0232 CALL WRITE_FLD_S3D_RL(
0233 I 'cg3d_r_I', 'I10', 1, Nr, cg3d_r, myIter, myThid )
0234 ENDIF
0235 firstResidual = SQRT(err_sq)
0236
0237 printResidual = .FALSE.
0238 IF ( debugLevel .GE. debLevZero ) THEN
0239 _BEGIN_MASTER( myThid )
0240 printResidual = printResidualFreq.GE.1
e6e223b277 Jean*0241 WRITE(standardMessageUnit,'(A,1P2E22.14)')
015c19607c Jean*0242 & ' cg3d: Sum(rhs),rhsMax = ',sumRHS,rhsMax
0243 _END_MASTER( myThid )
0244 ENDIF
0245
0246
0247
0248
0249 DO it3d=1, numIters
0250 IF ( err_sq.GE.cg3dTolerance_sq ) THEN
0251 err_sq = 0. _d 0
0252
0253 DO bj=myByLo(myThid),myByHi(myThid)
0254 DO bi=myBxLo(myThid),myBxHi(myThid)
0255 IF ( errTile(bi,bj).GE.cg3dTolerance_sq ) THEN
0256
0257
0258
0259
0260
0261
0262
0263 eta_qrNtile(bi,bj) = 0. _d 0
0264 DO k=1,1
0265 #ifdef TARGET_NEC_SX
0266
0267 #endif /* TARGET_NEC_SX */
0268 DO j=0,sNy+1
0269 DO i=0,sNx+1
0270 cg3d_q(i,j,k,bi,bj) = zMC(i,j,k,bi,bj)
0271 & *cg3d_r(i,j,k,bi,bj)
0272 ENDDO
0273 ENDDO
0274 ENDDO
0275 DO k=2,Nr
0276 #ifdef TARGET_NEC_SX
0277
0278 #endif /* TARGET_NEC_SX */
0279 DO j=0,sNy+1
0280 DO i=0,sNx+1
0281 cg3d_q(i,j,k,bi,bj) = zMC(i,j,k,bi,bj)
0282 & *( cg3d_r(i,j,k,bi,bj)
0283 & -zML(i,j,k,bi,bj)*cg3d_q(i,j,k-1,bi,bj)
0284 & )
0285 ENDDO
0286 ENDDO
0287 ENDDO
0288 DO k=Nr,Nr
0289 #ifdef TARGET_NEC_SX
0290
0291 #endif /* TARGET_NEC_SX */
0292 DO j=1,sNy
0293 DO i=1,sNx
0294 eta_qrNtile(bi,bj) = eta_qrNtile(bi,bj)
0295 & +cg3d_q(i,j,k,bi,bj)*cg3d_r(i,j,k,bi,bj)
0296 ENDDO
0297 ENDDO
0298 ENDDO
0299 DO k=Nr-1,1,-1
0300 #ifdef TARGET_NEC_SX
0301
0302 #endif /* TARGET_NEC_SX */
0303 DO j=0,sNy+1
0304 DO i=0,sNx+1
0305 cg3d_q(i,j,k,bi,bj) = cg3d_q(i,j,k,bi,bj)
0306 & -zMU(i,j,k,bi,bj)*cg3d_q(i,j,k+1,bi,bj)
0307 ENDDO
0308 ENDDO
0309 #ifdef TARGET_NEC_SX
0310
0311 #endif /* TARGET_NEC_SX */
0312 DO j=1,sNy
0313 DO i=1,sNx
0314 eta_qrNtile(bi,bj) = eta_qrNtile(bi,bj)
0315 & +cg3d_q(i,j,k,bi,bj)*cg3d_r(i,j,k,bi,bj)
0316 ENDDO
0317 ENDDO
0318 ENDDO
0319
0320 cgBeta = eta_qrNtile(bi,bj)/eta_qrNM1(bi,bj)
0321 eta_qrNM1(bi,bj) = eta_qrNtile(bi,bj)
0322
0323 DO k=1,Nr
0324 DO j=0,sNy+1
0325 DO i=0,sNx+1
0326 cg3d_s(i,j,k,bi,bj) = cg3d_q(i,j,k,bi,bj)
0327 & + cgBeta*cg3d_s(i,j,k,bi,bj)
0328 ENDDO
0329 ENDDO
0330 ENDDO
0331
0332
0333
0334 alphaTile(bi,bj) = 0. _d 0
0335 #ifdef NONLIN_FRSURF
0336 IF ( select_rStar .NE. 0 ) THEN
0337 DO j=1,sNy
0338 DO i=1,sNx
0339 surfTerm(i,j) = 0.
0340 ENDDO
0341 ENDDO
0342 DO k=1,Nr
0343 DO j=1,sNy
0344 DO i=1,sNx
0345 surfTerm(i,j) = surfTerm(i,j)
0346 & +cg3d_s(i,j,k,bi,bj)*drF(k)*h0FacC(i,j,k,bi,bj)
0347 ENDDO
0348 ENDDO
0349 ENDDO
0350 DO j=1,sNy
0351 DO i=1,sNx
0352 ks = kSurfC(i,j,bi,bj)
0353 surfTerm(i,j) = surfTerm(i,j)*cg3dNorm
0354 & *recip_Rcol(i,j,bi,bj)*recip_Rcol(i,j,bi,bj)
0355 & *rA(i,j,bi,bj)*deepFac2F(ks)
e6e223b277 Jean*0356 & *recip_Bo(i,j,bi,bj)/deltaTMom/deltaTFreeSurf
015c19607c Jean*0357 ENDDO
0358 ENDDO
0359 ENDIF
0360 #endif /* NONLIN_FRSURF */
0361 IF ( Nr .GT. 1 ) THEN
0362 k=1
0363 #ifdef TARGET_NEC_SX
0364
0365 #endif /* TARGET_NEC_SX */
0366 DO j=1,sNy
0367 DO i=1,sNx
0368 cg3d_q(i,j,k,bi,bj) =
0369 & aW3d( i, j, k, bi,bj)*cg3d_s(i-1,j, k, bi,bj)
0370 & +aW3d(i+1,j, k, bi,bj)*cg3d_s(i+1,j, k, bi,bj)
0371 & +aS3d( i, j, k, bi,bj)*cg3d_s( i,j-1,k, bi,bj)
0372 & +aS3d( i,j+1,k, bi,bj)*cg3d_s( i,j+1,k, bi,bj)
0373 & +aV3d( i, j,k+1,bi,bj)*cg3d_s( i, j,k+1,bi,bj)
0374 & +aC3d( i, j, k, bi,bj)*cg3d_s( i, j, k, bi,bj)
0375 #ifdef NONLIN_FRSURF
0376 & -surfFac*surfTerm(i,j)*drF(k)*h0FacC(i,j,k,bi,bj)
0377 #endif /* NONLIN_FRSURF */
0378 alphaTile(bi,bj) = alphaTile(bi,bj)
0379 & +cg3d_s(i,j,k,bi,bj)*cg3d_q(i,j,k,bi,bj)
0380 ENDDO
0381 ENDDO
0382 ELSE
0383 k=1
0384 #ifdef TARGET_NEC_SX
0385
0386 #endif /* TARGET_NEC_SX */
0387 DO j=1,sNy
0388 DO i=1,sNx
0389 cg3d_q(i,j,k,bi,bj) =
0390 & aW3d( i, j, k, bi,bj)*cg3d_s(i-1,j, k, bi,bj)
0391 & +aW3d(i+1,j, k, bi,bj)*cg3d_s(i+1,j, k, bi,bj)
0392 & +aS3d( i, j, k, bi,bj)*cg3d_s( i,j-1,k, bi,bj)
0393 & +aS3d( i,j+1,k, bi,bj)*cg3d_s( i,j+1,k, bi,bj)
0394 & +aC3d( i, j, k, bi,bj)*cg3d_s( i, j, k, bi,bj)
0395 #ifdef NONLIN_FRSURF
0396 & -surfFac*surfTerm(i,j)*drF(k)*h0FacC(i,j,k,bi,bj)
0397 #endif /* NONLIN_FRSURF */
0398 alphaTile(bi,bj) = alphaTile(bi,bj)
0399 & +cg3d_s(i,j,k,bi,bj)*cg3d_q(i,j,k,bi,bj)
0400 ENDDO
0401 ENDDO
0402 ENDIF
0403 DO k=2,Nr-1
0404 #ifdef TARGET_NEC_SX
0405
0406 #endif /* TARGET_NEC_SX */
0407 DO j=1,sNy
0408 DO i=1,sNx
0409 cg3d_q(i,j,k,bi,bj) =
0410 & aW3d( i, j, k, bi,bj)*cg3d_s(i-1,j, k, bi,bj)
0411 & +aW3d(i+1,j, k, bi,bj)*cg3d_s(i+1,j, k, bi,bj)
0412 & +aS3d( i, j, k, bi,bj)*cg3d_s( i,j-1,k, bi,bj)
0413 & +aS3d( i,j+1,k, bi,bj)*cg3d_s( i,j+1,k, bi,bj)
0414 & +aV3d( i, j, k, bi,bj)*cg3d_s( i, j,k-1,bi,bj)
0415 & +aV3d( i, j,k+1,bi,bj)*cg3d_s( i, j,k+1,bi,bj)
0416 & +aC3d( i, j, k, bi,bj)*cg3d_s( i, j, k, bi,bj)
0417 #ifdef NONLIN_FRSURF
0418 & -surfFac*surfTerm(i,j)*drF(k)*h0FacC(i,j,k,bi,bj)
0419 #endif /* NONLIN_FRSURF */
0420 alphaTile(bi,bj) = alphaTile(bi,bj)
0421 & +cg3d_s(i,j,k,bi,bj)*cg3d_q(i,j,k,bi,bj)
0422 ENDDO
0423 ENDDO
0424 ENDDO
0425 IF ( Nr .GT. 1 ) THEN
0426 k=Nr
0427 #ifdef TARGET_NEC_SX
0428
0429 #endif /* TARGET_NEC_SX */
0430 DO j=1,sNy
0431 DO i=1,sNx
0432 cg3d_q(i,j,k,bi,bj) =
0433 & aW3d( i, j, k, bi,bj)*cg3d_s(i-1,j, k, bi,bj)
0434 & +aW3d(i+1,j, k, bi,bj)*cg3d_s(i+1,j, k, bi,bj)
0435 & +aS3d( i, j, k, bi,bj)*cg3d_s( i,j-1,k, bi,bj)
0436 & +aS3d( i,j+1,k, bi,bj)*cg3d_s( i,j+1,k, bi,bj)
0437 & +aV3d( i, j, k, bi,bj)*cg3d_s( i, j,k-1,bi,bj)
0438 & +aC3d( i, j, k, bi,bj)*cg3d_s( i, j, k, bi,bj)
0439 #ifdef NONLIN_FRSURF
0440 & -surfFac*surfTerm(i,j)*drF(k)*h0FacC(i,j,k,bi,bj)
0441 #endif /* NONLIN_FRSURF */
0442 alphaTile(bi,bj) = alphaTile(bi,bj)
0443 & +cg3d_s(i,j,k,bi,bj)*cg3d_q(i,j,k,bi,bj)
0444 ENDDO
0445 ENDDO
0446 ENDIF
0447 alpha = eta_qrNtile(bi,bj)/alphaTile(bi,bj)
0448
0449
0450
0451 errTile(bi,bj) = 0. _d 0
0452 DO k=1,Nr
0453 #ifdef TARGET_NEC_SX
0454
0455 #endif /* TARGET_NEC_SX */
0456 DO j=1,sNy
0457 DO i=1,sNx
0458 cg3d_x(i,j,k,bi,bj)=cg3d_x(i,j,k,bi,bj)
0459 & +alpha*cg3d_s(i,j,k,bi,bj)
0460 cg3d_r(i,j,k,bi,bj)=cg3d_r(i,j,k,bi,bj)
0461 & -alpha*cg3d_q(i,j,k,bi,bj)
0462 errTile(bi,bj) = errTile(bi,bj)
0463 & +cg3d_r(i,j,k,bi,bj)*cg3d_r(i,j,k,bi,bj)
0464 ENDDO
0465 ENDDO
0466 ENDDO
0467 actualIts(bi,bj) = it3d
0468
0469 IF ( printResidual ) THEN
0470 IF ( MOD( it3d-1, printResidualFreq ).EQ.0 ) THEN
0471 WRITE(msgBuf,'(A,2I4,A,I6,A,1PE21.14)') ' cg3d(bi,bj=', bi,
0472 & bj, '): iter=', it3d, ' ; resid.= ', SQRT(errTile(bi,bj))
0473 CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
0474 & SQUEEZE_RIGHT, myThid )
0475 ENDIF
0476 ENDIF
0477
0478 CALL FILL_HALO_LOCAL_RL(
0479 U cg3d_r(0,0,1,bi,bj),
0480 I 1, 1, 1, 1, Nr,
0481 I EXCH_IGNORE_CORNERS, bi, bj, myThid )
0482
0483 ENDIF
0484 err_sq = MAX( errTile(bi,bj), err_sq )
0485
0486 ENDDO
0487 ENDDO
0488
0489 ENDIF
0490 ENDDO
0491
0492
0493
0494 IF ( debugLevel.GE.debLevC .AND. diagFreq.GT.0. ) THEN
0495 CALL WRITE_FLD_S3D_RL(
0496 I 'cg3d_r_F', 'I10', 1, Nr, cg3d_r, myIter, myThid )
0497 ENDIF
0498
0499
0500 numIters = 0
0501 DO bj=myByLo(myThid),myByHi(myThid)
0502 DO bi=myBxLo(myThid),myBxHi(myThid)
0503 DO k=1,Nr
0504 DO j=1,sNy
0505 DO i=1,sNx
0506 cg3d_x(i,j,k,bi,bj) = cg3d_x(i,j,k,bi,bj)/rhsNorm(bi,bj)
0507 ENDDO
0508 ENDDO
0509 ENDDO
0510 numIters = MAX( actualIts(bi,bj), numIters )
0511 ENDDO
0512 ENDDO
0513
0514
0515
0516 _GLOBAL_MAX_RL( err_sq, myThid )
0517 lastResidual = SQRT(err_sq)
0518 alpha = numIters
0519 _GLOBAL_MAX_RL( alpha, myThid )
0520 numIters = NINT( alpha )
0521
0522 #endif /* ALLOW_NONHYDROSTATIC */
0523
0524 RETURN
0525 END