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.
agrif_ice_interp.F90 in NEMO/trunk/src/NST – NEMO

source: NEMO/trunk/src/NST/agrif_ice_interp.F90 @ 9610

Last change on this file since 9610 was 9610, checked in by clem, 6 years ago

replace names of the agrif subroutines from si3 to ice

File size: 18.3 KB
RevLine 
[9596]1MODULE agrif_ice_interp
[7309]2   !!=====================================================================================
[9596]3   !!                       ***  MODULE agrif_ice_interp ***
[7309]4   !! Nesting module :  interp surface ice boundary condition from a parent grid
5   !! Sea-Ice model  :  LIM 3.6 Sea ice model time-stepping
6   !!=====================================================================================
7   !! History :  2.0   !  04-2008  (F. Dupont)  initial version
8   !!            3.4   !  09-2012  (R. Benshila, C. Herbaut) update and EVP
9   !!            3.6   !  05-2016  (C. Rousset)  Add LIM3 compatibility
10   !!----------------------------------------------------------------------
[9570]11#if defined key_agrif && defined key_si3 
[7309]12   !!----------------------------------------------------------------------
[9570]13   !!   'key_si3'  :                                 LIM 3.6 sea-ice model
[7309]14   !!   'key_agrif' :                                 AGRIF library
15   !!----------------------------------------------------------------------
[9610]16   !!  agrif_interp_ice    : interpolation of ice at "after" sea-ice time step
[7309]17   !!  agrif_interp_u_ice   : atomic routine to interpolate u_ice
18   !!  agrif_interp_v_ice   : atomic routine to interpolate v_ice
19   !!  agrif_interp_tra_ice : atomic routine to interpolate ice properties
20   !!----------------------------------------------------------------------
21   USE par_oce
22   USE dom_oce
23   USE sbc_oce
24   USE ice
25   USE agrif_ice
[9454]26   USE phycst , ONLY: rt0
[7309]27   
28   IMPLICIT NONE
29   PRIVATE
30
[9610]31   PUBLIC   agrif_interp_ice   ! called by agrif_user.F90
[7309]32
33   !!----------------------------------------------------------------------
[9598]34   !! NEMO/NST 3.6 , NEMO Consortium (2018)
[9596]35   !! $Id: agrif_ice_interp.F90 6204 2016-01-04 13:47:06Z cetlod $
[9598]36   !! Software governed by the CeCILL licence     (./LICENSE)
[7309]37   !!----------------------------------------------------------------------
38
39CONTAINS
40
[9610]41   SUBROUTINE agrif_interp_ice( cd_type, kiter, kitermax )
[7309]42      !!-----------------------------------------------------------------------
43      !!                 *** ROUTINE agrif_rhg_lim3  ***
44      !!
45      !!  ** Method  : simple call to atomic routines using stored values to
46      !!  fill the boundaries depending of the position of the point and
47      !!  computing factor for time interpolation
48      !!-----------------------------------------------------------------------
[9019]49      CHARACTER(len=1), INTENT(in   )           ::   cd_type
50      INTEGER         , INTENT(in   ), OPTIONAL ::   kiter, kitermax
[7309]51      !!
[9019]52      REAL(wp) ::   zbeta   ! local scalar
[7309]53      !!-----------------------------------------------------------------------
54      !
[9482]55      IF( Agrif_Root() .OR. nn_ice==0 )  RETURN   ! do not interpolate if inside Parent Grid or if child domain does not have ice
[7309]56      !
[9019]57      SELECT CASE( cd_type )
[7761]58      CASE('U','V')
[9482]59         IF( PRESENT( kiter ) ) THEN  ! interpolation at the child ice sub-time step (only for ice rheology)
[7761]60            zbeta = ( REAL(lim_nbstep) - REAL(kitermax - kiter) / REAL(kitermax) ) /  &
61               &    ( Agrif_Rhot() * REAL(Agrif_Parent(nn_fsbc)) / REAL(nn_fsbc) )
[9482]62         ELSE                         ! interpolation at the child ice time step
[7761]63            zbeta = REAL(lim_nbstep) / ( Agrif_Rhot() * REAL(Agrif_Parent(nn_fsbc)) / REAL(nn_fsbc) )
64         ENDIF
65      CASE('T')
[9160]66            zbeta = REAL(lim_nbstep) / ( Agrif_Rhot() * REAL(Agrif_Parent(nn_fsbc)) / REAL(nn_fsbc) )
[7761]67      END SELECT
[7309]68      !
[9019]69      Agrif_SpecialValue    = -9999.
[7309]70      Agrif_UseSpecialValue = .TRUE.
[9019]71      SELECT CASE( cd_type )
72      CASE('U')   ;   CALL Agrif_Bc_variable( u_ice_id  , procname=interp_u_ice  , calledweight=zbeta )
73      CASE('V')   ;   CALL Agrif_Bc_variable( v_ice_id  , procname=interp_v_ice  , calledweight=zbeta )
74      CASE('T')   ;   CALL Agrif_Bc_variable( tra_ice_id, procname=interp_tra_ice, calledweight=zbeta )
[7309]75      END SELECT
[9019]76      Agrif_SpecialValue    = 0._wp
[7309]77      Agrif_UseSpecialValue = .FALSE.
78      !
[9610]79   END SUBROUTINE agrif_interp_ice
[7309]80
[9019]81
[7309]82   SUBROUTINE interp_u_ice( ptab, i1, i2, j1, j2, before )
83      !!-----------------------------------------------------------------------
84      !!                     *** ROUTINE interp_u_ice ***
85      !!
86      !! i1 i2 j1 j2 are the index of the boundaries parent(when before) and child (when after)
[9019]87      !! To solve issues when parent grid is "land" masked but not all the corresponding child
88      !! grid points, put Agrif_SpecialValue WHERE the parent grid is masked.
89      !! The child solution will be found in the 9(?) points around
[7309]90      !!-----------------------------------------------------------------------
[9019]91      INTEGER                         , INTENT(in   ) ::   i1, i2, j1, j2
92      REAL(wp), DIMENSION(i1:i2,j1:j2), INTENT(inout) ::   ptab
93      LOGICAL                         , INTENT(in   ) ::   before
[7309]94      !!
[9019]95      REAL(wp) ::   zrhoy   ! local scalar
[7309]96      !!-----------------------------------------------------------------------
97      !
98      IF( before ) THEN  ! parent grid
[9160]99         ptab(:,:) = e2u(i1:i2,j1:j2) * u_ice(i1:i2,j1:j2)
[9019]100         WHERE( umask(i1:i2,j1:j2,1) == 0. )   ptab(i1:i2,j1:j2) = Agrif_SpecialValue
[7309]101      ELSE               ! child grid
102         zrhoy = Agrif_Rhoy()
[9019]103         u_ice(i1:i2,j1:j2) = ptab(i1:i2,j1:j2) / ( e2u(i1:i2,j1:j2) * zrhoy ) * umask(i1:i2,j1:j2,1)
[7309]104      ENDIF
105      !
106   END SUBROUTINE interp_u_ice
107
108
109   SUBROUTINE interp_v_ice( ptab, i1, i2, j1, j2, before )
110      !!-----------------------------------------------------------------------
111      !!                    *** ROUTINE interp_v_ice ***
112      !!
113      !! i1 i2 j1 j2 are the index of the boundaries parent(when before) and child (when after)
[9019]114      !! To solve issues when parent grid is "land" masked but not all the corresponding child
115      !! grid points, put Agrif_SpecialValue WHERE the parent grid is masked.
116      !! The child solution will be found in the 9(?) points around
[7309]117      !!-----------------------------------------------------------------------     
[9019]118      INTEGER                         , INTENT(in   ) ::   i1, i2, j1, j2
119      REAL(wp), DIMENSION(i1:i2,j1:j2), INTENT(inout) ::   ptab
120      LOGICAL                         , INTENT(in   ) ::   before
[7309]121      !!
[9019]122      REAL(wp) ::   zrhox   ! local scalar
[7309]123      !!-----------------------------------------------------------------------
124      !
125      IF( before ) THEN  ! parent grid
[9160]126         ptab(:,:) = e1v(i1:i2,j1:j2) * v_ice(i1:i2,j1:j2)
[9019]127         WHERE( vmask(i1:i2,j1:j2,1) == 0. )   ptab(i1:i2,j1:j2) = Agrif_SpecialValue
[7309]128      ELSE               ! child grid
129         zrhox = Agrif_Rhox()
[9019]130         v_ice(i1:i2,j1:j2) = ptab(i1:i2,j1:j2) / ( e1v(i1:i2,j1:j2) * zrhox ) * vmask(i1:i2,j1:j2,1)
[7309]131      ENDIF
132      !
133   END SUBROUTINE interp_v_ice
134
135
136   SUBROUTINE interp_tra_ice( ptab, i1, i2, j1, j2, k1, k2, before, nb, ndir )
137      !!-----------------------------------------------------------------------
138      !!                    *** ROUTINE interp_tra_ice ***                           
139      !!
140      !! i1 i2 j1 j2 are the index of the boundaries parent(when before) and child (when after)
[9019]141      !! To solve issues when parent grid is "land" masked but not all the corresponding child
142      !! grid points, put Agrif_SpecialValue WHERE the parent grid is masked.
143      !! The child solution will be found in the 9(?) points around
[7309]144      !!-----------------------------------------------------------------------
[9019]145      REAL(wp), DIMENSION(i1:i2,j1:j2,k1:k2), INTENT(inout) ::   ptab
146      INTEGER                               , INTENT(in   ) ::   i1, i2, j1, j2, k1, k2
147      LOGICAL                               , INTENT(in   ) ::   before
148      INTEGER                               , INTENT(in   ) ::   nb, ndir
[7309]149      !!
150      INTEGER  ::   ji, jj, jk, jl, jm
151      INTEGER  ::   imin, imax, jmin, jmax
[9019]152      LOGICAL  ::   western_side, eastern_side, northern_side, southern_side
[7309]153      REAL(wp) ::   zrhox, z1, z2, z3, z4, z5, z6, z7
[9019]154      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztab
[7309]155      !!-----------------------------------------------------------------------
[9019]156      ! tracers are not multiplied by grid cell here => before: * e1e2t ; after: * r1_e1e2t / rhox / rhoy
[7761]157      ! and it is ok since we conserve tracers (same as in the ocean).
[9019]158      ALLOCATE( ztab(SIZE(a_i,1),SIZE(a_i,2),SIZE(ptab,3)) )
[7309]159     
160      IF( before ) THEN  ! parent grid
161         jm = 1
162         DO jl = 1, jpl
[9160]163            ptab(i1:i2,j1:j2,jm  ) = a_i (i1:i2,j1:j2,jl)
164            ptab(i1:i2,j1:j2,jm+1) = v_i (i1:i2,j1:j2,jl)
165            ptab(i1:i2,j1:j2,jm+2) = v_s (i1:i2,j1:j2,jl)
166            ptab(i1:i2,j1:j2,jm+3) = sv_i(i1:i2,j1:j2,jl)
167            ptab(i1:i2,j1:j2,jm+4) = oa_i(i1:i2,j1:j2,jl)
[9167]168            ptab(i1:i2,j1:j2,jm+5) = a_ip(i1:i2,j1:j2,jl)
169            ptab(i1:i2,j1:j2,jm+6) = v_ip(i1:i2,j1:j2,jl)
170            ptab(i1:i2,j1:j2,jm+7) = t_su(i1:i2,j1:j2,jl)
171            jm = jm + 8
[7309]172            DO jk = 1, nlay_s
[9160]173               ptab(i1:i2,j1:j2,jm) = e_s(i1:i2,j1:j2,jk,jl)   ;   jm = jm + 1
[9019]174            END DO
[7309]175            DO jk = 1, nlay_i
[9160]176               ptab(i1:i2,j1:j2,jm) = e_i(i1:i2,j1:j2,jk,jl)   ;   jm = jm + 1
[9019]177            END DO
178         END DO
[7309]179         
180         DO jk = k1, k2
[9019]181            WHERE( tmask(i1:i2,j1:j2,1) == 0._wp )   ptab(i1:i2,j1:j2,jk) = Agrif_SpecialValue
182         END DO
183         !
[7309]184      ELSE               ! child grid
[9019]185         !
[9454]186!         IF( nbghostcells > 1 ) THEN   ! ==> The easiest interpolation is used
[9019]187            !
188            jm = 1
189            DO jl = 1, jpl
190               !
191               DO jj = j1, j2
192                  DO ji = i1, i2
193                     a_i (ji,jj,jl) = ptab(ji,jj,jm  ) * tmask(ji,jj,1)
194                     v_i (ji,jj,jl) = ptab(ji,jj,jm+1) * tmask(ji,jj,1)
195                     v_s (ji,jj,jl) = ptab(ji,jj,jm+2) * tmask(ji,jj,1)
196                     sv_i(ji,jj,jl) = ptab(ji,jj,jm+3) * tmask(ji,jj,1)
197                     oa_i(ji,jj,jl) = ptab(ji,jj,jm+4) * tmask(ji,jj,1)
[9167]198                     a_ip(ji,jj,jl) = ptab(ji,jj,jm+5) * tmask(ji,jj,1)
199                     v_ip(ji,jj,jl) = ptab(ji,jj,jm+6) * tmask(ji,jj,1)
200                     t_su(ji,jj,jl) = ptab(ji,jj,jm+7) * tmask(ji,jj,1)
[9019]201                  END DO
202               END DO
[9167]203               jm = jm + 8
[9019]204               !
205               DO jk = 1, nlay_s
[9482]206                  e_s(i1:i2,j1:j2,jk,jl) = ptab(i1:i2,j1:j2,jm) * tmask(i1:i2,j1:j2,1)
[9019]207                  jm = jm + 1
208               END DO
209               !
210               DO jk = 1, nlay_i
[9482]211                  e_i(i1:i2,j1:j2,jk,jl) = ptab(i1:i2,j1:j2,jm) * tmask(i1:i2,j1:j2,1)
[9019]212                  jm = jm + 1
213               END DO
214               !
215            END DO
216            !
[9454]217!!==> clem: this interpolation does not work because it creates negative values, due
[9482]218!!          to negative coefficients when mixing points (for ex. z7)
[9454]219!!
220!         ELSE                          ! ==> complex interpolation (only one ghost cell available)
221!            !! Use a more complex interpolation since we mix solutions over a couple of grid points
222!            !! it is advised to use it for fields modified by high order schemes (e.g. advection UM5...)
223!            ! record ztab
224!            jm = 1
225!            DO jl = 1, jpl
226!               ztab(:,:,jm  ) = a_i (:,:,jl)
227!               ztab(:,:,jm+1) = v_i (:,:,jl)
228!               ztab(:,:,jm+2) = v_s (:,:,jl)
229!               ztab(:,:,jm+3) = sv_i(:,:,jl)
230!               ztab(:,:,jm+4) = oa_i(:,:,jl)
231!               ztab(:,:,jm+5) = a_ip(:,:,jl)
232!               ztab(:,:,jm+6) = v_ip(:,:,jl)
233!               ztab(:,:,jm+7) = t_su(:,:,jl)
234!               jm = jm + 8
235!               DO jk = 1, nlay_s
236!                  ztab(:,:,jm) = e_s(:,:,jk,jl)
237!                  jm = jm + 1
238!               END DO
239!               DO jk = 1, nlay_i
240!                  ztab(:,:,jm) = e_i(:,:,jk,jl)
241!                  jm = jm + 1
242!               END DO
243!               !
244!            END DO
245!            !
246!            ! borders of the domain
247!            western_side  = (nb == 1).AND.(ndir == 1)  ;  eastern_side  = (nb == 1).AND.(ndir == 2)
248!            southern_side = (nb == 2).AND.(ndir == 1)  ;  northern_side = (nb == 2).AND.(ndir == 2)
249!            !
250!            ! spatial smoothing
251!            zrhox = Agrif_Rhox()
252!            z1 =      ( zrhox - 1. ) * 0.5
253!            z3 =      ( zrhox - 1. ) / ( zrhox + 1. )
254!            z6 = 2. * ( zrhox - 1. ) / ( zrhox + 1. )
255!            z7 =    - ( zrhox - 1. ) / ( zrhox + 3. )
256!            z2 = 1. - z1
257!            z4 = 1. - z3
258!            z5 = 1. - z6 - z7
259!            !
260!            ! Remove corners
261!            imin = i1  ;  imax = i2  ;  jmin = j1  ;  jmax = j2
262!            IF( (nbondj == -1) .OR. (nbondj == 2) )   jmin = 3
263!            IF( (nbondj == +1) .OR. (nbondj == 2) )   jmax = nlcj-2
264!            IF( (nbondi == -1) .OR. (nbondi == 2) )   imin = 3
265!            IF( (nbondi == +1) .OR. (nbondi == 2) )   imax = nlci-2
266!
267!            ! smoothed fields
268!            IF( eastern_side ) THEN
269!               ztab(nlci,j1:j2,:) = z1 * ptab(nlci,j1:j2,:) + z2 * ptab(nlci-1,j1:j2,:)
270!               DO jj = jmin, jmax
271!                  rswitch = 0.
272!                  IF( u_ice(nlci-2,jj) > 0._wp ) rswitch = 1.
273!                  ztab(nlci-1,jj,:) = ( 1. - umask(nlci-2,jj,1) ) * ztab(nlci,jj,:)  &
274!                     &                +      umask(nlci-2,jj,1)   *  &
275!                     &                ( ( 1. - rswitch ) * ( z4 * ztab(nlci,jj,:)   + z3 * ztab(nlci-2,jj,:) )  &
276!                     &                  +      rswitch   * ( z6 * ztab(nlci-2,jj,:) + z5 * ztab(nlci,jj,:) + z7 * ztab(nlci-3,jj,:) ) )
277!                  ztab(nlci-1,jj,:) = ztab(nlci-1,jj,:) * tmask(nlci-1,jj,1)
278!               END DO
279!            ENDIF
280!            !
281!            IF( northern_side ) THEN
282!               ztab(i1:i2,nlcj,:) = z1 * ptab(i1:i2,nlcj,:) + z2 * ptab(i1:i2,nlcj-1,:)
283!               DO ji = imin, imax
284!                  rswitch = 0.
285!                  IF( v_ice(ji,nlcj-2) > 0._wp ) rswitch = 1.
286!                  ztab(ji,nlcj-1,:) = ( 1. - vmask(ji,nlcj-2,1) ) * ztab(ji,nlcj,:)  &
287!                     &                +      vmask(ji,nlcj-2,1)   *  &
288!                     &                ( ( 1. - rswitch ) * ( z4 * ztab(ji,nlcj,:)   + z3 * ztab(ji,nlcj-2,:) ) &
289!                     &                  +      rswitch   * ( z6 * ztab(ji,nlcj-2,:) + z5 * ztab(ji,nlcj,:) + z7 * ztab(ji,nlcj-3,:) ) )
290!                  ztab(ji,nlcj-1,:) = ztab(ji,nlcj-1,:) * tmask(ji,nlcj-1,1)
291!               END DO
292!            END IF
293!            !
294!            IF( western_side) THEN
295!               ztab(1,j1:j2,:) = z1 * ptab(1,j1:j2,:) + z2 * ptab(2,j1:j2,:)
296!               DO jj = jmin, jmax
297!                  rswitch = 0.
298!                  IF( u_ice(2,jj) < 0._wp ) rswitch = 1.
299!                  ztab(2,jj,:) = ( 1. - umask(2,jj,1) ) * ztab(1,jj,:)  &
300!                     &           +      umask(2,jj,1)   *   &
301!                     &           ( ( 1. - rswitch ) * ( z4 * ztab(1,jj,:) + z3 * ztab(3,jj,:) ) &
302!                     &             +      rswitch   * ( z6 * ztab(3,jj,:) + z5 * ztab(1,jj,:) + z7 * ztab(4,jj,:) ) )
303!                  ztab(2,jj,:) = ztab(2,jj,:) * tmask(2,jj,1)
304!               END DO
305!            ENDIF
306!            !
307!            IF( southern_side ) THEN
308!               ztab(i1:i2,1,:) = z1 * ptab(i1:i2,1,:) + z2 * ptab(i1:i2,2,:)
309!               DO ji = imin, imax
310!                  rswitch = 0.
311!                  IF( v_ice(ji,2) < 0._wp ) rswitch = 1.
312!                  ztab(ji,2,:) = ( 1. - vmask(ji,2,1) ) * ztab(ji,1,:)  &
313!                     &           +      vmask(ji,2,1)   *  &
314!                     &           ( ( 1. - rswitch ) * ( z4 * ztab(ji,1,:) + z3 * ztab(ji,3,:) ) &
315!                     &             +      rswitch   * ( z6 * ztab(ji,3,:) + z5 * ztab(ji,1,:) + z7 * ztab(ji,4,:) ) )
316!                  ztab(ji,2,:) = ztab(ji,2,:) * tmask(ji,2,1)
317!               END DO
318!            END IF
319!            !
320!            ! Treatment of corners
321!            IF( (eastern_side) .AND. ((nbondj == -1).OR.(nbondj == 2)) )  ztab(nlci-1,2,:)      = ptab(nlci-1,2,:)      ! East south
322!            IF( (eastern_side) .AND. ((nbondj ==  1).OR.(nbondj == 2)) )  ztab(nlci-1,nlcj-1,:) = ptab(nlci-1,nlcj-1,:) ! East north
323!            IF( (western_side) .AND. ((nbondj == -1).OR.(nbondj == 2)) )  ztab(2,2,:)           = ptab(2,2,:)           ! West south
324!            IF( (western_side) .AND. ((nbondj ==  1).OR.(nbondj == 2)) )  ztab(2,nlcj-1,:)      = ptab(2,nlcj-1,:)      ! West north
325!           
326!            ! retrieve ice tracers
327!            jm = 1
328!            DO jl = 1, jpl
329!               !
330!               DO jj = j1, j2
331!                  DO ji = i1, i2
332!                     a_i (ji,jj,jl) = ztab(ji,jj,jm  ) * tmask(ji,jj,1)
333!                     v_i (ji,jj,jl) = ztab(ji,jj,jm+1) * tmask(ji,jj,1)
334!                     v_s (ji,jj,jl) = ztab(ji,jj,jm+2) * tmask(ji,jj,1)
335!                     sv_i(ji,jj,jl) = ztab(ji,jj,jm+3) * tmask(ji,jj,1)
336!                     oa_i(ji,jj,jl) = ztab(ji,jj,jm+4) * tmask(ji,jj,1)
337!                     a_ip(ji,jj,jl) = ztab(ji,jj,jm+5) * tmask(ji,jj,1)
338!                     v_ip(ji,jj,jl) = ztab(ji,jj,jm+6) * tmask(ji,jj,1)
339!                     t_su(ji,jj,jl) = ztab(ji,jj,jm+7) * tmask(ji,jj,1)
340!                  END DO
341!               END DO
342!               jm = jm + 8
343!               !
344!               DO jk = 1, nlay_s
345!                  e_s(i1:i2,j1:j2,jk,jl) = ztab(i1:i2,j1:j2,jm) * tmask(i1:i2,j1:j2,1)
346!                  jm = jm + 1
347!               END DO
348!               !
349!               DO jk = 1, nlay_i
350!                  e_i(i1:i2,j1:j2,jk,jl) = ztab(i1:i2,j1:j2,jm) * tmask(i1:i2,j1:j2,1)
351!                  jm = jm + 1
352!               END DO
353!               !
354!            END DO
355!         
356!         ENDIF  ! nbghostcells=1
[9019]357         
[9454]358         DO jl = 1, jpl
359            WHERE( tmask(i1:i2,j1:j2,1) == 0._wp )   t_su(i1:i2,j1:j2,jl) = rt0   ! to avoid a division by 0 in sbcblk.F90
360         END DO
361         !
[7309]362      ENDIF
363     
364      DEALLOCATE( ztab )
365      !
366   END SUBROUTINE interp_tra_ice
367
368#else
[9019]369   !!----------------------------------------------------------------------
370   !!   Empty module                                             no sea-ice
371   !!----------------------------------------------------------------------
[7309]372CONTAINS
[9596]373   SUBROUTINE agrif_ice_interp_empty
374      WRITE(*,*)  'agrif_ice_interp : You should not have seen this print! error?'
375   END SUBROUTINE agrif_ice_interp_empty
[7309]376#endif
[9019]377
378   !!======================================================================
[9596]379END MODULE agrif_ice_interp
Note: See TracBrowser for help on using the repository browser.