| 60 |
C loop indices |
C loop indices |
| 61 |
INTEGER newtonIter |
INTEGER newtonIter |
| 62 |
INTEGER krylovIter, krylovFails |
INTEGER krylovIter, krylovFails |
| 63 |
INTEGER totalKrylovItersLoc |
INTEGER totalKrylovItersLoc, totalNewtonItersLoc |
| 64 |
C FGMRES flag that determines amount of output messages of fgmres |
C FGMRES flag that determines amount of output messages of fgmres |
| 65 |
INTEGER iOutFGMRES |
INTEGER iOutFGMRES |
| 66 |
C FGMRES flag that indicates what fgmres wants us to do next |
C FGMRES flag that indicates what fgmres wants us to do next |
| 67 |
INTEGER iCode |
INTEGER iCode |
| 68 |
_RL JFNKresidual, JFNKresidualTile(nSx,nSy) |
_RL JFNKresidual |
| 69 |
_RL JFNKresidualKm1 |
_RL JFNKresidualKm1 |
| 70 |
C parameters to compute convergence criterion |
C parameters to compute convergence criterion |
| 71 |
_RL phi_e, alp_e, JFNKgamma_lin |
_RL phi_e, alp_e, JFNKgamma_lin |
| 74 |
C |
C |
| 75 |
_RL recip_deltaT |
_RL recip_deltaT |
| 76 |
LOGICAL JFNKconverged, krylovConverged |
LOGICAL JFNKconverged, krylovConverged |
| 77 |
|
LOGICAL writeNow |
| 78 |
CHARACTER*(MAX_LEN_MBUF) msgBuf |
CHARACTER*(MAX_LEN_MBUF) msgBuf |
| 79 |
C |
C |
| 80 |
C u/vIceRes :: residual of sea-ice momentum equations |
C u/vIceRes :: residual of sea-ice momentum equations |
| 81 |
_RL uIceRes(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL uIceRes(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 82 |
_RL vIceRes(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL vIceRes(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 83 |
|
C vector version of the residuals |
| 84 |
|
_RL resTmp (nVec,1,nSx,nSy) |
| 85 |
C du/vIce :: ice velocity increment to be added to u/vIce |
C du/vIce :: ice velocity increment to be added to u/vIce |
| 86 |
_RL duIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL duIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 87 |
_RL dvIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL dvIce (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 89 |
C zeta, eta, and DWATN, press |
C zeta, eta, and DWATN, press |
| 90 |
_RL zetaPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL zetaPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 91 |
_RL etaPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL etaPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 92 |
|
_RL etaZPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
| 93 |
_RL dwatPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
_RL dwatPre (1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
|
_RL pressPre(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nSx,nSy) |
|
| 94 |
CEOP |
CEOP |
| 95 |
|
|
| 96 |
C Initialise |
C Initialise |
| 105 |
recip_deltaT = 1. _d 0 / SEAICE_deltaTdyn |
recip_deltaT = 1. _d 0 / SEAICE_deltaTdyn |
| 106 |
|
|
| 107 |
iOutFGMRES=0 |
iOutFGMRES=0 |
| 108 |
C iOutFgmres=1 gives a little bit of output |
C with iOutFgmres=1, seaice_fgmres prints the residual at each iteration |
| 109 |
IF ( debugLevel.GE.debLevA .AND. |
IF ( debugLevel.GE.debLevC .AND. |
| 110 |
& DIFFERENT_MULTIPLE( SEAICE_monFreq, myTime, deltaTClock ) ) |
& DIFFERENT_MULTIPLE( SEAICE_monFreq, myTime, deltaTClock ) ) |
| 111 |
& iOutFGMRES=1 |
& iOutFGMRES=1 |
| 112 |
|
|
| 146 |
I uIce, vIce, |
I uIce, vIce, |
| 147 |
O uIceRes, vIceRes, |
O uIceRes, vIceRes, |
| 148 |
I newtonIter, 0, myTime, myIter, myThid ) |
I newtonIter, 0, myTime, myIter, myThid ) |
| 149 |
|
C probably not necessary, will be removed later: |
| 150 |
CALL EXCH_UV_XY_RL( uIceRes, vIceRes,.TRUE.,myThid) |
CALL EXCH_UV_XY_RL( uIceRes, vIceRes,.TRUE.,myThid) |
| 151 |
C local copies of precomputed coefficients that are to stay |
C local copies of precomputed coefficients that are to stay |
| 152 |
C constant for the preconditioner |
C constant for the preconditioner |
| 154 |
DO bi=myBxLo(myThid),myBxHi(myThid) |
DO bi=myBxLo(myThid),myBxHi(myThid) |
| 155 |
DO j=1-Oly,sNy+Oly |
DO j=1-Oly,sNy+Oly |
| 156 |
DO i=1-Olx,sNx+Olx |
DO i=1-Olx,sNx+Olx |
| 157 |
zetaPre(I,J,bi,bj) = zeta(I,J,bi,bj) |
zetaPre(I,J,bi,bj) = zeta(I,J,bi,bj) |
| 158 |
etaPre(I,J,bi,bj) = eta(I,J,bi,bj) |
etaPre(I,J,bi,bj) = eta(I,J,bi,bj) |
| 159 |
dwatPre(I,J,bi,bj) = DWATN(I,J,bi,bj) |
etaZPre(I,J,bi,bj) = etaZ(I,J,bi,bj) |
| 160 |
pressPre(I,J,bi,bj) = press(I,J,bi,bj) |
dwatPre(I,J,bi,bj) = DWATN(I,J,bi,bj) |
| 161 |
ENDDO |
ENDDO |
| 162 |
ENDDO |
ENDDO |
| 163 |
ENDDO |
ENDDO |
| 164 |
ENDDO |
ENDDO |
| 165 |
C |
C Important: Compute the norm of the residual using the same scalar |
| 166 |
DO bj=myByLo(myThid),myByHi(myThid) |
C product that SEAICE_FGMRES does |
| 167 |
DO bi=myBxLo(myThid),myBxHi(myThid) |
CALL SEAICE_MAP2VEC(nVec,uIceRes,vIceRes,resTmp,.TRUE.,myThid) |
| 168 |
JFNKresidualTile(bi,bj) = 0. _d 0 |
CALL SEAICE_SCALPROD( |
| 169 |
DO J=1,sNy |
& nVec,1,1,1,resTmp,resTmp,JFNKresidual,myThid) |
|
DO I=1,sNx |
|
|
#ifdef CG2D_SINGLECPU_SUM |
|
|
JFNKlocalBuf(I,J,bi,bj) = |
|
|
#else |
|
|
JFNKresidualTile(bi,bj) = JFNKresidualTile(bi,bj) + |
|
|
#endif |
|
|
& uIceRes(I,J,bi,bj)*uIceRes(I,J,bi,bj) + |
|
|
& vIceRes(I,J,bi,bj)*vIceRes(I,J,bi,bj) |
|
|
ENDDO |
|
|
ENDDO |
|
|
ENDDO |
|
|
ENDDO |
|
|
JFNKresidual = 0. _d 0 |
|
|
#ifdef CG2D_SINGLECPU_SUM |
|
|
CALL GLOBAL_SUM_SINGLECPU_RL( |
|
|
& JFNKlocalBuf,JFNKresidual, 0, 0, myThid) |
|
|
#else |
|
|
CALL GLOBAL_SUM_TILE_RL( JFNKresidualTile,JFNKresidual,myThid ) |
|
|
#endif |
|
| 170 |
JFNKresidual = SQRT(JFNKresidual) |
JFNKresidual = SQRT(JFNKresidual) |
| 171 |
C compute convergence criterion for linear preconditioned FGMRES |
C compute convergence criterion for linear preconditioned FGMRES |
| 172 |
JFNKgamma_lin = JFNKgamma_lin_max |
JFNKgamma_lin = JFNKgamma_lin_max |
| 189 |
C in that routine |
C in that routine |
| 190 |
krylovIter = 0 |
krylovIter = 0 |
| 191 |
iCode = 0 |
iCode = 0 |
|
IF ( debugLevel.GE.debLevA ) THEN |
|
|
_BEGIN_MASTER( myThid ) |
|
|
WRITE(msgBuf,'(2A,2(1XI6),2E12.5)') |
|
|
& ' S/R SEAICE_JFNK: newtonIter,', |
|
|
& ' total newtonIter, JFNKgamma_lin, initial norm = ', |
|
|
& newtonIter,SEAICEnewtonIterMax*(myIter-nIter0)+newtonIter, |
|
|
& JFNKgamma_lin, JFNKresidual |
|
|
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
|
|
& SQUEEZE_RIGHT, myThid ) |
|
|
_END_MASTER( myThid ) |
|
|
ENDIF |
|
| 192 |
C |
C |
| 193 |
JFNKconverged = JFNKresidual.LT.JFNKtol |
JFNKconverged = JFNKresidual.LT.JFNKtol |
| 194 |
C |
C |
| 214 |
C or product of matrix (Jacobian) times vector. For iCode = 0, terminate |
C or product of matrix (Jacobian) times vector. For iCode = 0, terminate |
| 215 |
C iteration |
C iteration |
| 216 |
IF (iCode.EQ.1) THEN |
IF (iCode.EQ.1) THEN |
| 217 |
C Call preconditioner |
C Call preconditioner |
| 218 |
CALL SEAICE_PRECONDITIONER( |
IF ( SOLV_MAX_ITERS .GT. 0 ) |
| 219 |
|
& CALL SEAICE_PRECONDITIONER( |
| 220 |
U duIce, dvIce, |
U duIce, dvIce, |
| 221 |
I zetaPre, etaPre, dwatPre, pressPre, |
I zetaPre, etaPre, etaZpre, dwatPre, |
| 222 |
I newtonIter, krylovIter, myTime, myIter, myThid ) |
I newtonIter, krylovIter, myTime, myIter, myThid ) |
| 223 |
ELSEIF (iCode.GE.2) THEN |
ELSEIF (iCode.GE.2) THEN |
| 224 |
C Compute Jacobian times vector |
C Compute Jacobian times vector |
| 234 |
C some output diagnostics |
C some output diagnostics |
| 235 |
IF ( debugLevel.GE.debLevA ) THEN |
IF ( debugLevel.GE.debLevA ) THEN |
| 236 |
_BEGIN_MASTER( myThid ) |
_BEGIN_MASTER( myThid ) |
| 237 |
|
totalNewtonItersLoc = |
| 238 |
|
& SEAICEnewtonIterMax*(myIter-nIter0)+newtonIter |
| 239 |
|
WRITE(msgBuf,'(2A,2(1XI6),2E12.5)') |
| 240 |
|
& ' S/R SEAICE_JFNK: Newton iterate / total, ', |
| 241 |
|
& 'JFNKgamma_lin, initial norm = ', |
| 242 |
|
& newtonIter, totalNewtonItersLoc, |
| 243 |
|
& JFNKgamma_lin,JFNKresidual |
| 244 |
|
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
| 245 |
|
& SQUEEZE_RIGHT, myThid ) |
| 246 |
WRITE(msgBuf,'(3(A,I6))') |
WRITE(msgBuf,'(3(A,I6))') |
| 247 |
& ' S/R SEAICE_JFNK: Newton iterate / total = ', newtonIter, |
& ' S/R SEAICE_JFNK: Newton iterate / total = ',newtonIter, |
| 248 |
& ' / ', SEAICEnewtonIterMax*(myIter-nIter0)+newtonIter, |
& ' / ', totalNewtonItersLoc, |
| 249 |
& ', Nb. of FGMRES iterations = ', krylovIter |
& ', Nb. of FGMRES iterations = ', krylovIter |
| 250 |
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
| 251 |
& SQUEEZE_RIGHT, myThid ) |
& SQUEEZE_RIGHT, myThid ) |
| 288 |
ENDIF |
ENDIF |
| 289 |
ENDIF |
ENDIF |
| 290 |
C Decide whether it is time to dump and reset the counter |
C Decide whether it is time to dump and reset the counter |
| 291 |
IF ( DIFFERENT_MULTIPLE(SEAICE_monFreq,myTime+deltaTClock, |
writeNow = DIFFERENT_MULTIPLE(SEAICE_monFreq, |
| 292 |
& deltaTClock) ) THEN |
& myTime+deltaTClock, deltaTClock) |
| 293 |
|
#ifdef ALLOW_CAL |
| 294 |
|
IF ( useCAL ) THEN |
| 295 |
|
CALL CAL_TIME2DUMP( |
| 296 |
|
I zeroRL, SEAICE_monFreq, deltaTClock, |
| 297 |
|
U writeNow, |
| 298 |
|
I myTime+deltaTclock, myIter+1, myThid ) |
| 299 |
|
ENDIF |
| 300 |
|
#endif |
| 301 |
|
IF ( writeNow ) THEN |
| 302 |
_BEGIN_MASTER( myThid ) |
_BEGIN_MASTER( myThid ) |
| 303 |
WRITE(msgBuf,'(A)') |
WRITE(msgBuf,'(A)') |
| 304 |
&' // =======================================================' |
&' // =======================================================' |
| 339 |
&' // =======================================================' |
&' // =======================================================' |
| 340 |
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
| 341 |
& SQUEEZE_RIGHT, myThid ) |
& SQUEEZE_RIGHT, myThid ) |
| 342 |
WRITE(msgBuf,'(A)') ' // Begin JFNK statistics' |
WRITE(msgBuf,'(A)') ' // End JFNK statistics' |
| 343 |
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
| 344 |
& SQUEEZE_RIGHT, myThid ) |
& SQUEEZE_RIGHT, myThid ) |
| 345 |
WRITE(msgBuf,'(A)') |
WRITE(msgBuf,'(A)') |