New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
limhdf.F90 in branches/2015/dev_r5044_CNRS_LIM3CLEAN/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2015/dev_r5044_CNRS_LIM3CLEAN/NEMOGCM/NEMO/LIM_SRC_3/limhdf.F90 @ 5048

Last change on this file since 5048 was 5047, checked in by clem, 9 years ago

LIM3 cleaning (1): namelist

  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1MODULE limhdf
2   !!======================================================================
3   !!                    ***  MODULE limhdf   ***
4   !! LIM ice model : horizontal diffusion of sea-ice quantities
5   !!======================================================================
6   !! History :  LIM  !  2000-01 (LIM) Original code
7   !!             -   !  2001-05 (G. Madec, R. Hordoir) opa norm
8   !!            1.0  !  2002-08 (C. Ethe)  F90, free form
9   !!----------------------------------------------------------------------
10#if defined key_lim3
11   !!----------------------------------------------------------------------
12   !!   'key_lim3'                                      LIM3 sea-ice model
13   !!----------------------------------------------------------------------
14   !!   lim_hdf       : diffusion trend on sea-ice variable
15   !!----------------------------------------------------------------------
16   USE dom_oce        ! ocean domain
17   USE ice            ! LIM-3: ice variables
18   USE lbclnk         ! lateral boundary condition - MPP exchanges
19   USE lib_mpp        ! MPP library
20   USE wrk_nemo       ! work arrays
21   USE prtctl         ! Print control
22   USE in_out_manager ! I/O manager
23   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
24
25   IMPLICIT NONE
26   PRIVATE
27
28   PUBLIC   lim_hdf     ! called by lim_tra
29
30   LOGICAL  ::   linit = .TRUE.              ! initialization flag (set to flase after the 1st call)
31   REAL(wp) ::   epsi04 = 1.e-04              ! constant
32   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   efact   ! metric coefficient
33
34   !! * Substitution
35#  include "vectopt_loop_substitute.h90"
36   !!----------------------------------------------------------------------
37   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2010)
38   !! $Id$
39   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
40   !!----------------------------------------------------------------------
41CONTAINS
42
43   SUBROUTINE lim_hdf( ptab )
44      !!-------------------------------------------------------------------
45      !!                  ***  ROUTINE lim_hdf  ***
46      !!
47      !! ** purpose :   Compute and add the diffusive trend on sea-ice variables
48      !!
49      !! ** method  :   Second order diffusive operator evaluated using a
50      !!              Cranck-Nicholson time Scheme.
51      !!
52      !! ** Action  :    update ptab with the diffusive contribution
53      !!-------------------------------------------------------------------
54      REAL(wp), DIMENSION(jpi,jpj), INTENT( inout ) ::   ptab    ! Field on which the diffusion is applied
55      !
56      INTEGER                           ::  ji, jj                   ! dummy loop indices
57      INTEGER                           ::  its, iter, ierr          ! local integers
58      REAL(wp)                          ::   zalfa, zrlxint, zconv   ! local scalars
59      REAL(wp), POINTER, DIMENSION(:,:) ::   zrlx, zflu, zflv, zdiv0, zdiv, ztab0
60      CHARACTER(lc)                     ::   charout                 ! local character
61      REAL(wp), PARAMETER               :: zrelax = 0.5_wp           ! relaxation constant for iterative procedure
62      !!-------------------------------------------------------------------
63     
64      CALL wrk_alloc( jpi, jpj, zrlx, zflu, zflv, zdiv0, zdiv, ztab0 )
65
66      !                       !==  Initialisation  ==!
67      !
68      IF( linit ) THEN              ! Metric coefficient (compute at the first call and saved in efact)
69         ALLOCATE( efact(jpi,jpj) , STAT=ierr )
70         IF( lk_mpp    )   CALL mpp_sum( ierr )
71         IF( ierr /= 0 )   CALL ctl_stop( 'STOP', 'lim_hdf : unable to allocate arrays' )
72         DO jj = 2, jpjm1 
73            DO ji = fs_2 , fs_jpim1   ! vector opt.
74               efact(ji,jj) = ( e2u(ji,jj) + e2u(ji-1,jj) + e1v(ji,jj) + e1v(ji,jj-1) ) / ( e1t(ji,jj) * e2t(ji,jj) )
75            END DO
76         END DO
77         linit = .FALSE.
78      ENDIF
79      !                             ! Time integration parameters
80      zalfa = 0.5_wp                      ! =1.0/0.5/0.0 = implicit/Cranck-Nicholson/explicit
81      its   = 100                         ! Maximum number of iteration
82      !
83      ztab0(:, : ) = ptab(:,:)      ! Arrays initialization
84      zdiv0(:, 1 ) = 0._wp
85      zdiv0(:,jpj) = 0._wp
86      zflu (jpi,:) = 0._wp   
87      zflv (jpi,:) = 0._wp
88      zdiv0(1,  :) = 0._wp
89      zdiv0(jpi,:) = 0._wp
90
91      zconv = 1._wp           !==  horizontal diffusion using a Crant-Nicholson scheme  ==!
92      iter  = 0
93      !
94      DO WHILE( zconv > ( 2._wp * epsi04 ) .AND. iter <= its )   ! Sub-time step loop
95         !
96         iter = iter + 1                                 ! incrementation of the sub-time step number
97         !
98         DO jj = 1, jpjm1                                ! diffusive fluxes in U- and V- direction
99            DO ji = 1 , fs_jpim1   ! vector opt.
100               zflu(ji,jj) = pahu(ji,jj) * e2u(ji,jj) / e1u(ji,jj) * ( ptab(ji+1,jj) - ptab(ji,jj) )
101               zflv(ji,jj) = pahv(ji,jj) * e1v(ji,jj) / e2v(ji,jj) * ( ptab(ji,jj+1) - ptab(ji,jj) )
102            END DO
103         END DO
104         !
105         DO jj= 2, jpjm1                                 ! diffusive trend : divergence of the fluxes
106            DO ji = fs_2 , fs_jpim1   ! vector opt.
107               zdiv (ji,jj) = (  zflu(ji,jj) - zflu(ji-1,jj  )   &
108                  &            + zflv(ji,jj) - zflv(ji  ,jj-1)  ) / ( e1t (ji,jj) * e2t (ji,jj) )
109            END DO
110         END DO
111         !
112         IF( iter == 1 )   zdiv0(:,:) = zdiv(:,:)        ! save the 1st evaluation of the diffusive trend in zdiv0
113         !
114         DO jj = 2, jpjm1                                ! iterative evaluation
115            DO ji = fs_2 , fs_jpim1   ! vector opt.
116               zrlxint = (   ztab0(ji,jj)    &
117                  &       +  rdt_ice * (           zalfa   * ( zdiv(ji,jj) + efact(ji,jj) * ptab(ji,jj) )   &
118                  &                      + ( 1.0 - zalfa ) *   zdiv0(ji,jj) )  )                             & 
119                  &    / ( 1.0 + zalfa * rdt_ice * efact(ji,jj) )
120               zrlx(ji,jj) = ptab(ji,jj) + zrelax * ( zrlxint - ptab(ji,jj) )
121            END DO
122         END DO
123         CALL lbc_lnk( zrlx, 'T', 1. )                   ! lateral boundary condition
124         !
125         zconv = 0._wp                                   ! convergence test
126         DO jj = 2, jpjm1
127            DO ji = fs_2, fs_jpim1
128               zconv = MAX( zconv, ABS( zrlx(ji,jj) - ptab(ji,jj) )  )
129            END DO
130         END DO
131         IF( lk_mpp )   CALL mpp_max( zconv )            ! max over the global domain
132         !
133         ptab(:,:) = zrlx(:,:)
134         !
135      END DO                                       ! end of sub-time step loop
136
137      ! -----------------------
138      !!! final step (clem) !!!
139      DO jj = 1, jpjm1                                ! diffusive fluxes in U- and V- direction
140         DO ji = 1 , fs_jpim1   ! vector opt.
141            zflu(ji,jj) = pahu(ji,jj) * e2u(ji,jj) / e1u(ji,jj) * ( ptab(ji+1,jj) - ptab(ji,jj) )
142            zflv(ji,jj) = pahv(ji,jj) * e1v(ji,jj) / e2v(ji,jj) * ( ptab(ji,jj+1) - ptab(ji,jj) )
143         END DO
144      END DO
145      !
146      DO jj= 2, jpjm1                                 ! diffusive trend : divergence of the fluxes
147         DO ji = fs_2 , fs_jpim1   ! vector opt.
148            zdiv (ji,jj) = (  zflu(ji,jj) - zflu(ji-1,jj  )   &
149                 &            + zflv(ji,jj) - zflv(ji  ,jj-1)  ) / ( e1t (ji,jj) * e2t (ji,jj) )
150            ptab(ji,jj) = ztab0(ji,jj) + 0.5 * ( zdiv(ji,jj) + zdiv0(ji,jj) )
151         END DO
152      END DO
153      CALL lbc_lnk( ptab, 'T', 1. )                   ! lateral boundary condition
154      !!! final step (clem) !!!
155      ! -----------------------
156
157      IF(ln_ctl)   THEN
158         zrlx(:,:) = ptab(:,:) - ztab0(:,:)
159         WRITE(charout,FMT="(' lim_hdf  : zconv =',D23.16, ' iter =',I4,2X)") zconv, iter
160         CALL prt_ctl( tab2d_1=zrlx, clinfo1=charout )
161      ENDIF
162      !
163      CALL wrk_dealloc( jpi, jpj, zrlx, zflu, zflv, zdiv0, zdiv, ztab0 )
164      !
165   END SUBROUTINE lim_hdf
166
167#else
168   !!----------------------------------------------------------------------
169   !!   Default option          Dummy module           NO LIM sea-ice model
170   !!----------------------------------------------------------------------
171CONTAINS
172   SUBROUTINE lim_hdf         ! Empty routine
173   END SUBROUTINE lim_hdf
174#endif
175
176   !!======================================================================
177END MODULE limhdf
Note: See TracBrowser for help on using the repository browser.