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.
Changeset 14623 – NEMO

Changeset 14623


Ignore:
Timestamp:
2021-03-21T19:40:22+01:00 (3 years ago)
Author:
ldebreu
Message:

AGFdomcfg: 1) Update DOMAINcfg to be compliant with the removal of halo cells 2) Update most of the LBC ... subroutines to a recent NEMO 4 version #2638

Location:
utils/tools/DOMAINcfg/src
Files:
9 added
40 edited

Legend:

Unmodified
Added
Removed
  • utils/tools/DOMAINcfg/src/agrif_connect.F90

    r13204 r14623  
    7474         ELSEWHERE 
    7575           ssmask(i1:i2,j1:j2) = 1. 
    76          END WHERE            
     76         END WHERE   
    7777      ENDIF 
    7878      ! 
     
    146146                  IF( e3t_interp(ji,jj,jk) == -10 ) THEN ! the connection has not yet been done 
    147147                     e3t_interp(ji,jj,jk) = MAX( ptab(ji,jj,jk),MIN(e3zps_min, e3t_1d(jk)*e3zps_rat) ) 
    148                      e3t_interp(ji,jj,jk) = MIN( e3t_interp(ji,jj,jk),e3t_1d(jk) ) 
     148                  !   e3t_interp(ji,jj,jk) = MIN( e3t_interp(ji,jj,jk),e3t_1d(jk) ) 
    149149                     e3t_0(ji,jj,jk) = ( 1. - ztabramp(ji,jj) )*e3t_0(ji,jj,jk) + ztabramp(ji,jj)*e3t_interp(ji,jj,jk) 
    150150                  ENDIF 
     
    180180      ! --- West --- ! 
    181181      IF( ((nbondi == -1) .OR. (nbondi == 2) ).AND. .NOT. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6)) THEN 
    182          ind1 = 1+nbghostcells + istart 
     182         ind1 = nn_hls + 1 + nbghostcells + istart 
    183183         ind2 = ind1 + ispongearea  
    184          DO jj = 1, jpj 
    185             DO ji = ind1, ind2                 
    186                ztabramp(ji,jj) = REAL( ind2 - ji ) * z1_spongearea * umask(ind1,jj,1) 
    187             END DO 
    188          ENDDO 
     184         DO ji = mi0(ind1), mi1(ind2)    
     185            DO jj = 1, jpj                
     186               ztabramp(ji,jj) = REAL(ind2 - mig(ji), wp) * z1_spongearea * umask(ind1,jj,1) 
     187            END DO 
     188         ENDDO 
     189            ! ghost cells: 
     190            ind1 = 1 
     191            ind2 = nn_hls + 1 + nbghostcells + istart  ! halo + land + nbghostcells 
     192            DO ji = mi0(ind1), mi1(ind2)    
     193               DO jj = 1, jpj                
     194                  ztabramp(ji,jj) = 1._wp 
     195               END DO 
     196            END DO 
    189197      ENDIF 
    190198 
    191199      ! --- East --- ! 
    192200      IF( ((nbondi == 1) .OR. (nbondi == 2) ).AND. .NOT. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6)) THEN 
    193          ind2 = nlci - nbghostcells - istart 
     201         ind2 = jpiglo -  (nn_hls + nbghostcells ) - istart 
    194202         ind1 = ind2 -ispongearea        
    195          DO jj = 1, jpj 
    196             DO ji = ind1, ind2 
    197                ztabramp(ji,jj) = MAX( ztabramp(ji,jj), REAL( ji - ind1 ) * z1_spongearea * umask(ind2-1,jj,1) ) 
     203         DO ji = mi0(ind1), mi1(ind2) 
     204            DO jj = 1, jpj 
     205               ztabramp(ji,jj) = MAX( ztabramp(ji,jj), REAL( mig(ji) - ind1 ) * z1_spongearea * umask(ind2-1,jj,1) ) 
    198206            ENDDO 
    199207         ENDDO 
     208            ! ghost cells: 
     209            ind1 = jpiglo -  (nn_hls + nbghostcells ) - istart   ! halo + land + nbghostcells - 1 
     210            ind2 = jpiglo - 1 
     211            DO ji = mi0(ind1), mi1(ind2) 
     212               DO jj = 1, jpj 
     213                  ztabramp(ji,jj) = 1._wp 
     214               END DO 
     215            END DO 
    200216      ENDIF 
    201217 
    202218      ! --- South --- ! 
    203219      IF(( (nbondj == -1) .OR. (nbondj == 2) ).AND.(lk_south)) THEN 
    204          ind1 = 1+nbghostcells + istart 
     220         ind1 = nn_hls + 1 + nbghostcells + istart 
    205221         ind2 = ind1 + ispongearea  
    206          DO jj = ind1, ind2  
     222         DO jj = mj0(ind1), mj1(ind2)  
    207223            DO ji = 1, jpi 
    208                ztabramp(ji,jj) = MAX( ztabramp(ji,jj), REAL( ind2 - jj ) * z1_spongearea * vmask(ji,ind1,1) ) 
    209             END DO 
    210          ENDDO 
     224               ztabramp(ji,jj) = MAX( ztabramp(ji,jj), REAL( ind2 - mjg(jj) ) * z1_spongearea * vmask(ji,ind1,1) ) 
     225            END DO 
     226         ENDDO 
     227            ! ghost cells: 
     228            ind1 = 1 
     229            ind2 = nn_hls + 1 + nbghostcells + istart                 ! halo + land + nbghostcells 
     230            DO jj = mj0(ind1), mj1(ind2)  
     231               DO ji = 1, jpi 
     232                  ztabramp(ji,jj) = 1._wp 
     233               END DO 
     234            END DO 
    211235      ENDIF 
    212236 
    213237      ! --- North --- ! 
    214238      IF( (nbondj == 1) .OR. (nbondj == 2) ) THEN 
    215          ind2 = nlcj - nbghostcells - istart 
    216          ind1 = ind2 -ispongearea          
    217          DO jj = ind1, ind2 
     239         ind2 = jpjglo - (nn_hls + nbghostcells) - istart 
     240         ind1 = ind2 -ispongearea 
     241         DO jj = mj0(ind1), mj1(ind2) 
    218242            DO ji = 1, jpi 
    219                ztabramp(ji,jj) = MAX( ztabramp(ji,jj), REAL( jj - ind1 ) * z1_spongearea * vmask(ji,ind2-1,1) ) 
    220             END DO 
    221          ENDDO 
     243               ztabramp(ji,jj) = MAX( ztabramp(ji,jj), REAL( mjg(jj) - ind1 ) * z1_spongearea * vmask(ji,ind2-1,1) ) 
     244            END DO 
     245         ENDDO 
     246            ! ghost cells: 
     247            ind1 = jpjglo - (nn_hls + nbghostcells) - istart      ! halo + land + nbghostcells - 1 
     248            ind2 = jpjglo 
     249            DO jj = mj0(ind1), mj1(ind2) 
     250               DO ji = 1, jpi 
     251                  ztabramp(ji,jj) = 1._wp 
     252               END DO 
     253            END DO 
    222254      ENDIF 
    223255      ! 
  • utils/tools/DOMAINcfg/src/agrif_dom_update.F90

    r13204 r14623  
    7676            DO jj=j1,j2 
    7777               DO ji=i1,i2 
    78                    IF( mbkt(ji,jj) .GE. jk ) THEN 
     78                   IF ((ssmask(ji,jj) /=0.).AND.( mbkt(ji,jj) .GE. jk )) THEN 
    7979                      tabres(ji,jj,jk) = e3t_0(ji,jj,jk) 
    8080                   ELSE 
     
    9090                   IF( mbkt(ji,jj) .GE. jk ) THEN 
    9191                      e3t_0(ji,jj,jk) = MAX(tabres(ji,jj,jk),MIN(e3zps_min,e3t_1d(jk)*e3zps_rat)) 
     92                  !    e3t_0(ji,jj,jk) = tabres(ji,jj,jk) 
    9293                   ELSE 
    9394                      e3t_0(ji,jj,jk) = e3t_1d(jk) 
     
    9798         END DO 
    9899 
    99          CALL lbc_lnk('update_e3t',e3t_0,'T',1.) 
     100         CALL lbc_lnk('update_e3t',e3t_0,'T',1.,kfillmode = jpfillcopy) 
    100101         ! 
    101102      ENDIF 
  • utils/tools/DOMAINcfg/src/agrif_user.F90

    r14606 r14623  
    4545      IMPLICIT NONE 
    4646      ! 
    47       INTEGER :: nx, ny 
    4847      INTEGER :: irafx, irafy 
    4948      LOGICAL :: ln_perio 
     
    5251      irafy = agrif_irhoy() 
    5352 
    54       nx = nlci ; ny = nlcj 
    5553 
    5654   !       IF(jperio /=1 .AND. jperio/=4 .AND. jperio/=6 ) THEN 
     
    7169 
    7270      WRITE(*,*) ' ' 
    73       WRITE(*,*)'Size of the High resolution grid: ',nx,' x ',ny 
     71      WRITE(*,*)'Size of the High resolution grid: ',jpi,' x ',jpj 
    7472      WRITE(*,*) ' ' 
    7573 
     
    202200 
    203201      INTEGER :: ind1, ind2, ind3 
    204       INTEGER :: nx, ny 
    205202      INTEGER ::nbghostcellsfine_tot_x, nbghostcellsfine_tot_y 
    206203      INTEGER :: irafx 
     
    211208      !--------------------------------------------------------------------- 
    212209 
    213       nx=nlci ; ny=nlcj 
    214  
    215       ind2 = 2 + nbghostcells_x 
    216       ind3 = 2 + nbghostcells_y_s 
     210      ind2 = nn_hls + 2 + nbghostcells_x 
     211      ind3 = nn_hls + 2 + nbghostcells_y_s 
     212 
    217213      nbghostcellsfine_tot_x=nbghostcells_x+1 
    218214      nbghostcellsfine_tot_y=max(nbghostcells_y_s,nbghostcells_y_n)+1 
     
    230226      endif 
    231227 
    232       CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),glamt_id) 
    233       CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),glamu_id) 
    234       CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),glamv_id) 
    235       CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),glamf_id) 
    236  
    237       CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),gphit_id) 
    238       CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),gphiu_id) 
    239       CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),gphiv_id) 
    240       CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),gphif_id) 
     228      CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),glamt_id) 
     229      CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),glamu_id) 
     230      CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),glamv_id) 
     231      CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),glamf_id) 
     232 
     233      CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),gphit_id) 
     234      CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),gphiu_id) 
     235      CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),gphiv_id) 
     236      CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),gphif_id) 
    241237 
    242238      ! Horizontal scale factors 
    243239 
    244       CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),e1t_id) 
    245       CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),e1u_id) 
    246       CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),e1v_id) 
    247       CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),e1f_id) 
    248  
    249       CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),e2t_id) 
    250       CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),e2u_id) 
    251       CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),e2v_id) 
    252       CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/nx,ny/),e2f_id) 
     240      CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e1t_id) 
     241      CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e1u_id) 
     242      CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e1v_id) 
     243      CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e1f_id) 
     244 
     245      CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e2t_id) 
     246      CALL agrif_declare_variable((/1,2/),(/ind2-1,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e2u_id) 
     247      CALL agrif_declare_variable((/2,1/),(/ind2,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e2v_id) 
     248      CALL agrif_declare_variable((/1,1/),(/ind2-1,ind3-1/),(/'x','y'/),(/1,1/),(/jpi,jpj/),e2f_id) 
    253249 
    254250      ! Bathymetry 
    255251 
    256       CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),bathy_id) 
     252      CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),bathy_id) 
    257253 
    258254      ! Vertical scale factors 
    259       CALL agrif_declare_variable((/2,2,0/),(/ind2,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/nx,ny,jpk/),e3t_id) 
    260       CALL agrif_declare_variable((/2,2,0/),(/ind2,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/nx,ny,jpk/),e3t_copy_id) 
    261       CALL agrif_declare_variable((/2,2,0/),(/ind2,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/nx,ny,jpk+1/),e3t_connect_id) 
    262  
    263       CALL agrif_declare_variable((/1,2,0/),(/ind2-1,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/nx,ny,jpk/),e3u_id) 
    264       CALL agrif_declare_variable((/2,1,0/),(/ind2,ind3-1,0/),(/'x','y','N'/),(/1,1,1/),(/nx,ny,jpk/),e3v_id) 
     255      CALL agrif_declare_variable((/2,2,0/),(/ind2,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/jpi,jpj,jpk/),e3t_id) 
     256      CALL agrif_declare_variable((/2,2,0/),(/ind2,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/jpi,jpj,jpk/),e3t_copy_id) 
     257      CALL agrif_declare_variable((/2,2,0/),(/ind2,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/jpi,jpj,jpk+1/),e3t_connect_id) 
     258 
     259      CALL agrif_declare_variable((/1,2,0/),(/ind2-1,ind3,0/),(/'x','y','N'/),(/1,1,1/),(/jpi,jpj,jpk/),e3u_id) 
     260      CALL agrif_declare_variable((/2,1,0/),(/ind2,ind3-1,0/),(/'x','y','N'/),(/1,1,1/),(/jpi,jpj,jpk/),e3v_id) 
    265261 
    266262      ! Bottom level 
    267263 
    268       CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/nx,ny/),bottom_level_id) 
     264      CALL agrif_declare_variable((/2,2/),(/ind2,ind3/),(/'x','y'/),(/1,1/),(/jpi,jpj/),bottom_level_id) 
    269265 
    270266      CALL Agrif_Set_bcinterp(glamt_id,interp=AGRIF_linear) 
     
    348344      CALL Agrif_Set_bc( e3t_copy_id, (/-npt_copy*irafx,max(nbghostcellsfine_tot_x,nbghostcellsfine_tot_y)-1/)) 
    349345 
    350       CALL Agrif_Set_bcinterp(e3t_connect_id,interp=AGRIF_ppm) 
    351       CALL Agrif_Set_interp(e3t_connect_id,interp=AGRIF_ppm) 
     346      CALL Agrif_Set_bcinterp(e3t_connect_id,interp=AGRIF_linear) 
     347      CALL Agrif_Set_interp(e3t_connect_id,interp=AGRIF_linear) 
    352348      CALL Agrif_Set_bc( e3t_connect_id, (/-(npt_copy+npt_connect)*irafx-1,-npt_copy*irafx/)) 
    353349 
     
    589585      EXTERNAL :: init_glamt, init_glamu, init_glamv, init_glamf 
    590586      EXTERNAL :: init_gphit, init_gphiu, init_gphiv, init_gphif 
    591       REAL, EXTERNAL :: longitude_linear_interp 
    592  
    593       INTEGER :: ji,jj,i1,i2,j1,j2 
    594       REAL, DIMENSION(jpi,jpj) :: tab2dtemp 
    595       INTEGER :: ind2,ind3 
    596       INTEGER :: irhox, irhoy 
    597  
    598       irhox = agrif_irhox() 
    599       irhoy = agrif_irhoy() 
     587      EXTERNAL :: longitude_linear_interp 
     588 
    600589      CALL Agrif_Set_external_linear_interp(longitude_linear_interp) 
    601590 
     
    637626      USE lbclnk 
    638627      LOGICAL :: ln_perio 
    639       INTEGER nx,ny 
     628      INTEGER jpi,jpj 
    640629 
    641630      EXTERNAL :: init_e1t, init_e1u, init_e1v, init_e1f 
    642631      EXTERNAL :: init_e2t, init_e2u, init_e2v, init_e2f 
    643  
    644       nx = nlci ; ny = nlcj 
    645632 
    646633      ln_perio=.FALSE. 
     
    10781065      &  npt_copy 
    10791066 
    1080       REWIND( numnam_ref )              ! Namelist namagrif in reference namelist : nesting parameters 
     1067  !    REWIND( numnam_ref )              ! Namelist namagrif in reference namelist : nesting parameters 
    10811068      READ  ( numnam_ref, namagrif, IOSTAT = ios, ERR = 901 ) 
    1082 901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namagrif in reference namelist', lwp ) 
    1083  
    1084       REWIND( numnam_cfg )              ! Namelist namzgr in configuration namelist : nesting parameters 
     1069901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namagrif in reference namelist') 
     1070 
     1071  !    REWIND( numnam_cfg )              ! Namelist namzgr in configuration namelist : nesting parameters 
    10851072      READ  ( numnam_cfg, namagrif, IOSTAT = ios, ERR = 902 ) 
    1086 902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namagrif in configuration namelist', lwp ) 
     1073902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namagrif in configuration namelist') 
    10871074      IF(lwm) WRITE ( numond, namagrif ) 
    10881075 
     
    11021089      nbghostcells_y_n = nbghostcells 
    11031090 
     1091      IF ((jperio == 1).OR.(jperio == 4)) THEN 
     1092        nbghostcells_x = 0 
     1093      ENDIF 
     1094      IF (jperio == 4) THEN 
     1095        nbghostcells_y_s = 0 
     1096      ENDIF 
     1097 
     1098      IF (.not.agrif_root()) THEN 
    11041099      lk_west  = .NOT. ( Agrif_Ix() == 1 ) 
    11051100      lk_east  = .NOT. ( Agrif_Ix() + nbcellsx/AGRIF_Irhox() == Agrif_Parent(jpiglo) -1 ) 
    11061101      lk_south = .NOT. ( Agrif_Iy() == 1 ) 
    11071102      lk_north = .NOT. ( Agrif_Iy() + nbcellsy/AGRIF_Irhoy() == Agrif_Parent(jpjglo) -1 ) 
    1108  
    1109       IF (.not.agrif_root()) THEN 
    1110         IF (jperio == 1) THEN 
    1111           nbghostcells_x = 0 
    1112         ENDIF 
    11131103        IF (.NOT.lk_south) THEN 
    11141104          nbghostcells_y_s = 0 
     
    11461136      ! 
    11471137      SELECT CASE( i ) 
    1148       CASE(1)   ;   indglob = indloc + nimppt(nprocloc+1) - 1 
    1149       CASE(2)   ;   indglob = indloc + njmppt(nprocloc+1) - 1 
     1138      CASE(1)   ;   indglob = mig(indloc) 
     1139      CASE(2)   ;   indglob = mjg(indloc) 
    11501140      CASE DEFAULT 
    11511141         indglob = indloc 
  • utils/tools/DOMAINcfg/src/calendar.f90

    r6951 r14623  
    11MODULE calendar 
     2!$AGRIF_DO_NOT_TREAT 
    23!- 
    34!$Id: calendar.f90 2459 2010-12-07 11:17:48Z smasson $ 
     
    10421043!=== 
    10431044!- 
     1045!$AGRIF_END_DO_NOT_TREAT 
    10441046END MODULE calendar 
  • utils/tools/DOMAINcfg/src/dom_oce.F90

    r13390 r14623  
    151151   INTEGER             , PUBLIC ::   nbondi, nbondj   !: mark of i- and j-direction local boundaries 
    152152 
     153   !                             !: domain MPP decomposition parameters 
     154   INTEGER             , PUBLIC ::   nimpp, njmpp     !: i- & j-indexes for mpp-subdomain left bottom 
     155   INTEGER             , PUBLIC ::   nproc            !: number for local processor 
     156   INTEGER             , PUBLIC ::   narea            !: number for local area 
     157   INTEGER             , PUBLIC ::   nbondi, nbondj   !: mark of i- and j-direction local boundaries 
     158   INTEGER, ALLOCATABLE, PUBLIC ::   nbondi_bdy(:)    !: mark i-direction local boundaries for BDY open boundaries 
     159   INTEGER, ALLOCATABLE, PUBLIC ::   nbondj_bdy(:)    !: mark j-direction local boundaries for BDY open boundaries 
     160   INTEGER, ALLOCATABLE, PUBLIC ::   nbondi_bdy_b(:)  !: mark i-direction of neighbours local boundaries for BDY open boundaries   
     161   INTEGER, ALLOCATABLE, PUBLIC ::   nbondj_bdy_b(:)  !: mark j-direction of neighbours local boundaries for BDY open boundaries   
     162 
    153163   INTEGER, PUBLIC ::   npolj             !: north fold mark (0, 3 or 4) 
    154    INTEGER, PUBLIC ::   nlci, nldi, nlei  !: i-dimensions of the local subdomain and its first and last indoor indices 
    155    INTEGER, PUBLIC ::   nlcj, nldj, nlej  !: i-dimensions of the local subdomain and its first and last indoor indices 
    156164   INTEGER, PUBLIC ::   noea, nowe        !: index of the local neighboring processors in 
    157165   INTEGER, PUBLIC ::   noso, nono        !: east, west, south and north directions 
    158166   INTEGER, PUBLIC ::   nidom             !: ??? 
    159167 
    160    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mig        !: local  ==> global domain i-index 
    161    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mjg        !: local  ==> global domain j-index 
    162    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mi0, mi1   !: global ==> local  domain i-index (mi0=1 and mi1=0 if the global index 
    163    !                                                                !                                             is not in the local domain) 
    164    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mj0, mj1   !: global ==> local  domain j-index (mj0=1 and mj1=0 if the global index 
    165    !                                                                !                                             is not in the local domain) 
    166    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nimppt, njmppt   !: i-, j-indexes for each processor 
    167    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   ibonit, ibonjt   !: i-, j- processor neighbour existence 
    168    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nlcit , nlcjt    !: dimensions of every subdomain 
    169    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nldit , nldjt    !: first, last indoor index for each i-domain 
    170    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nleit , nlejt    !: first, last indoor index for each j-domain 
    171    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: nfiimpp, nfipproc, nfilcit 
     168   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mig        !: local ==> global domain, including halos (jpiglo), i-index 
     169   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mjg        !: local ==> global domain, including halos (jpjglo), j-index 
     170   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mig0       !: local ==> global domain, excluding halos (Ni0glo), i-index 
     171   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mjg0       !: local ==> global domain, excluding halos (Nj0glo), j-index 
     172   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mig0_oldcmp !: local ==> global domain, excluding halos (Ni0glo), i-index 
     173   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mjg0_oldcmp !: local ==> global domain, excluding halos (Nj0glo), j-index 
     174   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mi0, mi1   !: global, including halos (jpiglo) ==> local domain i-index 
     175   !                                                                !:    (mi0=1 and mi1=0 if global index not in local domain) 
     176   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   mj0, mj1   !: global, including halos (jpjglo) ==> local domain j-index 
     177   !                                                                !:    (mj0=1 and mj1=0 if global index not in local domain) 
     178   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nimppt,  njmppt   !: i-, j-indexes for each processor 
     179   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   ibonit,  ibonjt   !: i-, j- processor neighbour existence 
     180   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   jpiall,  jpjall   !: dimensions of all subdomain 
     181   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nis0all, njs0all  !: first, last indoor index for all i-subdomain 
     182   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nie0all, nje0all  !: first, last indoor index for all j-subdomain 
     183   INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   nfimpp, nfproc, nfjpi 
     184 
    172185 
    173186   !!---------------------------------------------------------------------- 
     
    312325      ierr(:) = 0 
    313326      ! 
    314       ALLOCATE( mig(jpi), mjg(jpj), STAT=ierr(1) ) 
     327      ALLOCATE( mig(jpi), mjg(jpj), mig0(jpi), mjg0(jpj), mig0_oldcmp(jpi), mjg0_oldcmp(jpj),& 
     328                STAT=ierr(1) ) 
    315329         ! 
    316330      ALLOCATE( mi0(jpiglo)   , mi1 (jpiglo),  mj0(jpjglo)   , mj1 (jpjglo) ,     & 
  • utils/tools/DOMAINcfg/src/domain.F90

    r14199 r14623  
    7676      !                       !==  Reference coordinate system  ==! 
    7777      ! 
     78      CALL dom_glo                     ! global domain versus local domain 
    7879      CALL dom_nam               ! read namelist ( namrun, namdom ) 
     80                  !   CALL dom_clo               ! Closed seas and lake 
    7981          
    8082      CALL dom_hgr               ! Horizontal mesh 
    8183      CALL dom_zgr( ik_top, ik_bot )  ! Vertical mesh and bathymetry 
    8284      CALL dom_msk( ik_top, ik_bot )  ! Masks 
    83       IF ( ln_domclo ) CALL dom_clo               ! Closed seas and lake 
     85      ! 
    8486      ! 
    8587      CALL dom_ctl                  ! print extrema of masked scale factors 
     
    9193   END SUBROUTINE dom_init 
    9294 
     95   SUBROUTINE dom_glo 
     96      !!---------------------------------------------------------------------- 
     97      !!                     ***  ROUTINE dom_glo  *** 
     98      !! 
     99      !! ** Purpose :   initialization of global domain <--> local domain indices 
     100      !! 
     101      !! ** Method  :    
     102      !! 
     103      !! ** Action  : - mig , mjg : local  domain indices ==> global domain, including halos, indices 
     104      !!              - mig0, mjg0: local  domain indices ==> global domain, excluding halos, indices 
     105      !!              - mi0 , mi1 : global domain indices ==> local  domain indices 
     106      !!              - mj0 , mj1   (if global point not in the local domain ==> mi0>mi1 and/or mj0>mj1) 
     107      !!---------------------------------------------------------------------- 
     108      INTEGER ::   ji, jj   ! dummy loop argument 
     109      !!---------------------------------------------------------------------- 
     110      ! 
     111      DO ji = 1, jpi                 ! local domain indices ==> global domain, including halos, indices 
     112        mig(ji) = ji + nimpp - 1 
     113      END DO 
     114      DO jj = 1, jpj 
     115        mjg(jj) = jj + njmpp - 1 
     116      END DO 
     117      !                              ! local domain indices ==> global domain, excluding halos, indices 
     118      ! 
     119      mig0(:) = mig(:) - nn_hls 
     120      mjg0(:) = mjg(:) - nn_hls   
     121      ! WARNING: to keep compatibility with the trunk that was including periodocity into the input data,  
     122      ! we must define mig0 and mjg0 as bellow. 
     123      ! Once we decide to forget trunk compatibility, we must simply define mig0 and mjg0 as: 
     124      mig0_oldcmp(:) = mig0(:) + COUNT( (/ jperio == 1 .OR. jperio == 4 .OR. jperio == 6 .OR. jperio == 7 /) ) 
     125      mjg0_oldcmp(:) = mjg0(:) + COUNT( (/ jperio == 2 .OR. jperio == 7 /) ) 
     126      ! 
     127      !                              ! global domain, including halos, indices ==> local domain indices 
     128      !                                   ! (return (m.0,m.1)=(1,0) if data domain gridpoint is to the west/south of the  
     129      !                                   ! local domain, or (m.0,m.1)=(jp.+1,jp.) to the east/north of local domain.  
     130      DO ji = 1, jpiglo 
     131        mi0(ji) = MAX( 1 , MIN( ji - nimpp + 1, jpi+1 ) ) 
     132        mi1(ji) = MAX( 0 , MIN( ji - nimpp + 1, jpi   ) ) 
     133      END DO 
     134      DO jj = 1, jpjglo 
     135        mj0(jj) = MAX( 1 , MIN( jj - njmpp + 1, jpj+1 ) ) 
     136        mj1(jj) = MAX( 0 , MIN( jj - njmpp + 1, jpj   ) ) 
     137      END DO 
     138      IF(lwp) THEN                   ! control print 
     139         WRITE(numout,*) 
     140         WRITE(numout,*) 'dom_glo : domain: global <<==>> local ' 
     141         WRITE(numout,*) '~~~~~~~ ' 
     142         WRITE(numout,*) '   global domain:   jpiglo = ', jpiglo, ' jpjglo = ', jpjglo, ' jpkglo = ', jpkglo 
     143         WRITE(numout,*) '   local  domain:   jpi    = ', jpi   , ' jpj    = ', jpj   , ' jpk    = ', jpk 
     144         WRITE(numout,*) 
     145      ENDIF 
     146      ! 
     147   END SUBROUTINE dom_glo 
     148 
    93149   SUBROUTINE dom_nam 
    94150      !!---------------------------------------------------------------------- 
     
    108164 
    109165      NAMELIST/namdom/ ln_read_cfg, nn_bathy, cn_domcfg, cn_topo, cn_bath, cn_lon, cn_lat, rn_scale, nn_interp, & 
    110          &             cn_topolvl, cn_fisfd, cn_visfd, cn_bathlvl, cn_fcoord,                       &  
     166         &             cn_topolvl, cn_fisfd, cn_visfd, cn_bathlvl, cn_fcoord,                        &  
    111167         &             rn_bathy , rn_e3zps_min, rn_e3zps_rat, nn_msh, rn_hmin,                       & 
    112168         &             rn_atfp , rn_rdt   ,  ln_crs      , jphgr_msh ,                               & 
     
    116172 
    117173      INTEGER  ::   ios                 ! Local integer output status for namelist read 
    118       !!---------------------------------------------------------------------- 
    119  
    120       REWIND( numnam_ref )              ! Namelist namrun in reference namelist : Parameters of the run 
     174      CHARACTER(256) :: c_iomsg 
     175      !!---------------------------------------------------------------------- 
     176 
     177    
    121178      READ  ( numnam_ref, namrun, IOSTAT = ios, ERR = 901) 
    122 901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namrun in reference namelist', lwp ) 
    123  
    124       REWIND( numnam_cfg )              ! Namelist namrun in configuration namelist : Parameters of the run 
    125       READ  ( numnam_cfg, namrun, IOSTAT = ios, ERR = 902 ) 
    126 902   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namrun in configuration namelist', lwp ) 
     179901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namrun in reference namelist') 
     180 
     181      READ  ( numnam_cfg, namrun, IOSTAT = ios, IOMSG = c_iomsg, ERR = 902 ) 
     182 
     183902   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namrun in configuration namelist') 
    127184      IF(lwm) WRITE ( numond, namrun ) 
    128185      ! 
     
    152209      rn_scale = 1. 
    153210 
    154       REWIND( numnam_ref )              ! Namelist namdom in reference namelist : space & time domain (bathymetry, mesh, timestep) 
     211      !REWIND( numnam_ref )              ! Namelist namdom in reference namelist : space & time domain (bathymetry, mesh, timestep) 
    155212      READ  ( numnam_ref, namdom, IOSTAT = ios, ERR = 903) 
    156 903   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in reference namelist', lwp ) 
     213903   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in reference namelist' ) 
    157214   
    158215      ! 
    159       REWIND( numnam_cfg )              ! Namelist namdom in configuration namelist : space & time domain (bathymetry, mesh, timestep) 
     216      !REWIND( numnam_cfg )              ! Namelist namdom in configuration namelist : space & time domain (bathymetry, mesh, timestep) 
    160217      READ  ( numnam_cfg, namdom, IOSTAT = ios, ERR = 904 ) 
    161 904   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in configuration namelist', lwp ) 
     218904   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namdom in configuration namelist' ) 
    162219      IF(lwm) WRITE ( numond, namdom ) 
    163220      ! 
  • utils/tools/DOMAINcfg/src/dombat.F90

    r13204 r14623  
    4949      latname=TRIM(cn_lat) 
    5050    
    51       CALL iom_open( bathyfile, inum, lagrif=.FALSE. ) 
     51      CALL iom_open( bathyfile, inum, ldiof=.TRUE. ) 
    5252       
    5353      ! check if lon/lat are 2D arrays 
     
    404404        !             
    405405      ENDIF 
    406       CALL lbc_lnk( 'dom_bat', bathy, 'T', 1. ) 
     406      CALL lbc_lnk( 'dom_bat', bathy, 'T', 1.,kfillmode = jpfillcopy) 
    407407 
    408408       ! Correct South and North 
    409 #if defined key_agrif 
    410       IF( lk_south ) THEN   
    411          IF( (nbondj == -1).OR.(nbondj == 2) ) THEN 
    412            bathy(:,1)=bathy(:,2) 
    413          ENDIF 
    414       ELSE 
    415             bathy(:,1) = 0. 
    416       ENDIF 
    417 #else 
    418       IF ((nbondj == -1).OR.(nbondj == 2)) THEN 
    419             bathy(:,1)=bathy(:,2) 
    420       ENDIF 
    421 #endif 
    422  
    423       IF ((nbondj == 1).OR.(nbondj == 2)) THEN 
    424          bathy(:,jpj)=bathy(:,jpj-1) 
    425       ENDIF 
    426  
    427       ! Correct West and East 
    428       IF (jperio /=1) THEN 
    429          IF ((nbondi == -1).OR.(nbondi == 2)) THEN 
    430             bathy(1,:)=bathy(2,:) 
    431          ENDIF 
    432          IF ((nbondi == 1).OR.(nbondi == 2)) THEN 
    433          bathy(jpi,:)=bathy(jpi-1,:) 
    434          ENDIF 
    435       ENDIF 
     409! #if defined key_agrif 
     410!       IF( lk_south ) THEN   
     411!          IF( (nbondj == -1).OR.(nbondj == 2) ) THEN 
     412!            bathy(:,1)=bathy(:,2) 
     413!          ENDIF 
     414!       ELSE 
     415!             bathy(:,1) = 0. 
     416!       ENDIF 
     417! #else 
     418!       IF ((nbondj == -1).OR.(nbondj == 2)) THEN 
     419!             bathy(:,1)=bathy(:,2) 
     420!       ENDIF 
     421! #endif 
     422 
     423!       IF ((nbondj == 1).OR.(nbondj == 2)) THEN 
     424!          bathy(:,jpj)=bathy(:,jpj-1) 
     425!       ENDIF 
     426 
     427!       ! Correct West and East 
     428!       IF (jperio /=1) THEN 
     429!          IF ((nbondi == -1).OR.(nbondi == 2)) THEN 
     430!             bathy(1,:)=bathy(2,:) 
     431!          ENDIF 
     432!          IF ((nbondi == 1).OR.(nbondi == 2)) THEN 
     433!          bathy(jpi,:)=bathy(jpi-1,:) 
     434!          ENDIF 
     435!       ENDIF 
    436436 
    437437 
  • utils/tools/DOMAINcfg/src/domcfg.f90

    r13204 r14623  
    5555      IF( jperio <  0 .OR. jperio > 6 )   CALL ctl_stop( 'jperio is out of range' ) 
    5656      ! 
    57       CALL dom_glo                   ! global domain versus zoom and/or local domain 
    58       ! 
    5957   END SUBROUTINE dom_cfg 
    6058 
    61    SUBROUTINE dom_glo 
    62       !!---------------------------------------------------------------------- 
    63       !!                     ***  ROUTINE dom_glo  *** 
    64       !! 
    65       !! ** Purpose :   initialization of global domain <--> local domain indices 
    66       !! 
    67       !! ** Method  :    
    68       !! 
    69       !! ** Action  : - mig , mjg : local  domain indices ==> global domain indices 
    70       !!              - mi0 , mi1 : global domain indices ==> local  domain indices 
    71       !!              - mj0,, mj1   (global point not in the local domain ==> mi0>mi1 and/or mj0>mj1) 
    72       !!---------------------------------------------------------------------- 
    73       INTEGER ::   ji, jj   ! dummy loop argument 
    74       !!---------------------------------------------------------------------- 
    75       ! 
    76       DO ji = 1, jpi                 ! local domain indices ==> global domain indices 
    77         mig(ji) = ji + nimpp - 1 
    78       END DO 
    79       DO jj = 1, jpj 
    80         mjg(jj) = jj + njmpp - 1 
    81       END DO 
    82       !                              ! global domain indices ==> local domain indices 
    83       !                                   ! (return (m.0,m.1)=(1,0) if data domain gridpoint is to the west/south of the  
    84       !                                   ! local domain, or (m.0,m.1)=(jp.+1,jp.) to the east/north of local domain.  
    85       DO ji = 1, jpiglo 
    86         mi0(ji) = MAX( 1 , MIN( ji - nimpp + 1, jpi+1 ) ) 
    87         mi1(ji) = MAX( 0 , MIN( ji - nimpp + 1, jpi   ) ) 
    88       END DO 
    89       DO jj = 1, jpjglo 
    90         mj0(jj) = MAX( 1 , MIN( jj - njmpp + 1, jpj+1 ) ) 
    91         mj1(jj) = MAX( 0 , MIN( jj - njmpp + 1, jpj   ) ) 
    92       END DO 
    93       IF(lwp) THEN                   ! control print 
    94          WRITE(numout,*) 
    95          WRITE(numout,*) 'dom_glo : domain: global <<==>> local ' 
    96          WRITE(numout,*) '~~~~~~~ ' 
    97          WRITE(numout,*) '   global domain:   jpiglo = ', jpiglo, ' jpjglo = ', jpjglo, ' jpkglo = ', jpkglo 
    98          WRITE(numout,*) '   local  domain:   jpi    = ', jpi   , ' jpj    = ', jpj   , ' jpk    = ', jpk 
    99          WRITE(numout,*) 
    100          WRITE(numout,*) '   conversion from local to global domain indices (and vise versa) done' 
    101  
    102 !            WRITE(numout,*) 
    103 !            WRITE(numout,*) '          conversion local  ==> global i-index domain (mig)' 
    104 !            WRITE(numout,25)              (mig(ji),ji = 1,jpi) 
    105 !            WRITE(numout,*) 
    106 !            WRITE(numout,*) '          conversion global ==> local  i-index domain' 
    107 !            WRITE(numout,*) '             starting index (mi0)' 
    108 !            WRITE(numout,25)              (mi0(ji),ji = 1,jpiglo) 
    109 !            WRITE(numout,*) '             ending index (mi1)' 
    110 !            WRITE(numout,25)              (mi1(ji),ji = 1,jpiglo) 
    111 !            WRITE(numout,*) 
    112 !            WRITE(numout,*) '          conversion local  ==> global j-index domain (mjg)' 
    113 !            WRITE(numout,25)              (mjg(jj),jj = 1,jpj) 
    114 !            WRITE(numout,*) 
    115 !            WRITE(numout,*) '          conversion global ==> local  j-index domain' 
    116 !            WRITE(numout,*) '             starting index (mj0)' 
    117 !            WRITE(numout,25)              (mj0(jj),jj = 1,jpjglo) 
    118 !            WRITE(numout,*) '             ending index (mj1)' 
    119 !            WRITE(numout,25)              (mj1(jj),jj = 1,jpjglo) 
    120       ENDIF 
    121  25   FORMAT( 100(10x,19i4,/) ) 
    122       ! 
    123    END SUBROUTINE dom_glo 
    12459   !!====================================================================== 
    12560END MODULE domcfg 
  • utils/tools/DOMAINcfg/src/domclo.F90

    r13204 r14623  
    9393      !!--------------------------------------------------------------------- 
    9494       
    95       REWIND( numnam_ref )              ! Namelist namlbc in reference namelist : Lateral momentum boundary condition 
     95   !   REWIND( numnam_ref )              ! Namelist namlbc in reference namelist : Lateral momentum boundary condition 
    9696      READ  ( numnam_ref, namclo, IOSTAT = ios, ERR = 901 ) 
    97 901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namclo in reference namelist', lwp ) 
    98       REWIND( numnam_cfg )              ! Namelist namlbc in configuration namelist : Lateral momentum boundary condition 
     97901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namclo in reference namelist') 
     98   !   REWIND( numnam_cfg )              ! Namelist namlbc in configuration namelist : Lateral momentum boundary condition 
    9999      READ  ( numnam_cfg, namclo, IOSTAT = ios, ERR = 902 ) 
    100 902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namclo in configuration namelist', lwp ) 
     100902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namclo in configuration namelist') 
    101101      IF(lwm) WRITE ( numond, namclo ) 
    102102 
  • utils/tools/DOMAINcfg/src/domhgr.F90

    r13390 r14623  
    392392         IF(lwp) THEN 
    393393            WRITE(numout,*)  
    394             WRITE(numout,*) '          Beta-plane: Beta parameter = constant = ', ff_f(nldi,nldj) 
    395             WRITE(numout,*) '          Coriolis parameter varies from ', ff_f(nldi,nldj),' to ', ff_f(nldi,nlej) 
     394            WRITE(numout,*) '          Beta-plane: Beta parameter = constant = ', ff_f(Nis0,Njs0) 
     395            WRITE(numout,*) '          Coriolis parameter varies from ', ff_f(Nis0,Njs0),' to ', ff_f(Nis0,Nje0) 
    396396         ENDIF 
    397397         IF( lk_mpp ) THEN  
    398             zminff=ff_f(nldi,nldj) 
    399             zmaxff=ff_f(nldi,nlej) 
     398            zminff=ff_f(Nis0,Njs0) 
     399            zmaxff=ff_f(Nis0,Nje0) 
    400400            CALL mpp_min( 'toto',zminff )   ! min over the global domain 
    401401            CALL mpp_max( 'toto',zmaxff )   ! max over the global domain 
     
    415415            WRITE(numout,*)  
    416416            WRITE(numout,*) '          Beta-plane and rotated domain : ' 
    417             WRITE(numout,*) '          Coriolis parameter varies in this processor from ', ff_f(nldi,nldj),' to ', ff_f(nldi,nlej) 
     417            WRITE(numout,*) '          Coriolis parameter varies in this processor from ', ff_f(Nis0,Njs0),' to ', ff_f(Nis0,Nje0) 
    418418         ENDIF 
    419419         ! 
    420420         IF( lk_mpp ) THEN  
    421             zminff=ff_f(nldi,nldj) 
    422             zmaxff=ff_f(nldi,nlej) 
     421            zminff=ff_f(Nis0,Njs0) 
     422            zmaxff=ff_f(Nis0,Nje0) 
    423423            CALL mpp_min('toto', zminff )   ! min over the global domain 
    424424            CALL mpp_max( 'toto',zmaxff )   ! max over the global domain 
     
    462462      ENDIF 
    463463      ! 
     464 
    464465      IF (ln_read_cfg) THEN 
    465466         coordinate_filename=TRIM(cn_domcfg) 
     
    469470      CALL iom_open( coordinate_filename, inum ) 
    470471      ! 
    471       CALL iom_get( inum, jpdom_data, 'glamt', glamt, lrowattr=ln_use_jattr ) 
    472       CALL iom_get( inum, jpdom_data, 'glamu', glamu, lrowattr=ln_use_jattr ) 
    473       CALL iom_get( inum, jpdom_data, 'glamv', glamv, lrowattr=ln_use_jattr ) 
    474       CALL iom_get( inum, jpdom_data, 'glamf', glamf, lrowattr=ln_use_jattr ) 
    475       ! 
    476       CALL iom_get( inum, jpdom_data, 'gphit', gphit, lrowattr=ln_use_jattr ) 
    477       CALL iom_get( inum, jpdom_data, 'gphiu', gphiu, lrowattr=ln_use_jattr ) 
    478       CALL iom_get( inum, jpdom_data, 'gphiv', gphiv, lrowattr=ln_use_jattr ) 
    479       CALL iom_get( inum, jpdom_data, 'gphif', gphif, lrowattr=ln_use_jattr ) 
    480       ! 
    481       CALL iom_get( inum, jpdom_data, 'e1t'  , e1t  , lrowattr=ln_use_jattr ) 
    482       CALL iom_get( inum, jpdom_data, 'e1u'  , e1u  , lrowattr=ln_use_jattr ) 
    483       CALL iom_get( inum, jpdom_data, 'e1v'  , e1v  , lrowattr=ln_use_jattr ) 
    484       CALL iom_get( inum, jpdom_data, 'e1f'  , e1f  , lrowattr=ln_use_jattr ) 
    485       ! 
    486       CALL iom_get( inum, jpdom_data, 'e2t'  , e2t  , lrowattr=ln_use_jattr ) 
    487       CALL iom_get( inum, jpdom_data, 'e2u'  , e2u  , lrowattr=ln_use_jattr ) 
    488       CALL iom_get( inum, jpdom_data, 'e2v'  , e2v  , lrowattr=ln_use_jattr ) 
    489       CALL iom_get( inum, jpdom_data, 'e2f'  , e2f  , lrowattr=ln_use_jattr ) 
     472      CALL iom_get( inum, jpdom_global, 'glamt', glamt, cd_type = 'T', psgn = 1._wp ) 
     473      CALL iom_get( inum, jpdom_global, 'glamu', glamu, cd_type = 'U', psgn = 1._wp ) 
     474      CALL iom_get( inum, jpdom_global, 'glamv', glamv, cd_type = 'V', psgn = 1._wp ) 
     475      CALL iom_get( inum, jpdom_global, 'glamf', glamf, cd_type = 'F', psgn = 1._wp ) 
     476      ! 
     477      CALL iom_get( inum, jpdom_global, 'gphit', gphit, cd_type = 'T', psgn = 1._wp ) 
     478      CALL iom_get( inum, jpdom_global, 'gphiu', gphiu, cd_type = 'U', psgn = 1._wp ) 
     479      CALL iom_get( inum, jpdom_global, 'gphiv', gphiv, cd_type = 'V', psgn = 1._wp ) 
     480      CALL iom_get( inum, jpdom_global, 'gphif', gphif, cd_type = 'F', psgn = 1._wp ) 
     481      ! 
     482      CALL iom_get( inum, jpdom_global, 'e1t'  , e1t , cd_type = 'T', psgn = 1._wp, kfill = jpfillcopy ) 
     483      CALL iom_get( inum, jpdom_global, 'e1u'  , e1u , cd_type = 'U', psgn = 1._wp, kfill = jpfillcopy ) 
     484      CALL iom_get( inum, jpdom_global, 'e1v'  , e1v , cd_type = 'V', psgn = 1._wp, kfill = jpfillcopy ) 
     485      CALL iom_get( inum, jpdom_global, 'e1f'  , e1f , cd_type = 'F', psgn = 1._wp, kfill = jpfillcopy ) 
     486      ! 
     487      CALL iom_get( inum, jpdom_global, 'e2t'  , e2t , cd_type = 'T', psgn = 1._wp, kfill = jpfillcopy ) 
     488      CALL iom_get( inum, jpdom_global, 'e2u'  , e2u , cd_type = 'U', psgn = 1._wp, kfill = jpfillcopy ) 
     489      CALL iom_get( inum, jpdom_global, 'e2v'  , e2v , cd_type = 'V', psgn = 1._wp, kfill = jpfillcopy ) 
     490      CALL iom_get( inum, jpdom_global, 'e2f'  , e2f , cd_type = 'F', psgn = 1._wp, kfill = jpfillcopy ) 
    490491      ! 
    491492      IF( iom_varid( inum, 'e1e2u', ldstop = .FALSE. ) > 0 ) THEN 
    492493         IF(lwp) WRITE(numout,*) 'hgr_read : e1e2u & e1e2v read in coordinates file' 
    493          CALL iom_get( inum, jpdom_data, 'e1e2u'  , e1e2u  , lrowattr=ln_use_jattr ) 
    494          CALL iom_get( inum, jpdom_data, 'e1e2v'  , e1e2v  , lrowattr=ln_use_jattr ) 
     494         CALL iom_get( inum, jpdom_global, 'e1e2u', e1e2u, cd_type = 'U', psgn = 1._wp, kfill = jpfillcopy ) 
     495         CALL iom_get( inum, jpdom_global, 'e1e2v', e1e2v, cd_type = 'V', psgn = 1._wp, kfill = jpfillcopy ) 
    495496         ke1e2u_v = 1 
    496497      ELSE 
  • utils/tools/DOMAINcfg/src/domisf.F90

    r14199 r14623  
    5959      ! 
    6060      ! 0.0 read namelist 
    61       REWIND( numnam_ref )              ! Namelist namzgr_isf in reference namelist : ice shelf geometry definition 
     61 !     REWIND( numnam_ref )              ! Namelist namzgr_isf in reference namelist : ice shelf geometry definition 
    6262      READ  ( numnam_ref, namzgr_isf, IOSTAT = ios, ERR = 901) 
    63 901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_isf in reference namelist', lwp ) 
    64  
    65       REWIND( numnam_cfg )              ! Namelist namzgr_sco in configuration namelist : ice shelf geometry definition 
     63901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_isf in reference namelist') 
     64 
     65 !     REWIND( numnam_cfg )              ! Namelist namzgr_sco in configuration namelist : ice shelf geometry definition 
    6666      READ  ( numnam_cfg, namzgr_isf, IOSTAT = ios, ERR = 902 ) 
    67 902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_isf in configuration namelist', lwp ) 
     67902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_isf in configuration namelist') 
    6868      IF(lwm) WRITE ( numond, namzgr_isf ) 
    6969      ! 
     
    295295         zrisfdep = risfdep 
    296296         WHERE ( mbathy(:,:) == 0 ) 
    297             imask(:,:) = jpk 
     297            imask(:,:) = 0 
    298298            imbathy(:,:) = jpk 
    299299         END WHERE 
     
    302302               IF(  (misfdep(ji,jj) > 1) .AND. (mbathy(ji,jj) > 0) ) THEN 
    303303                  ! 
    304                   ! what it should be (1 = should be connected; >= jpk = should not be connected) 
     304                  ! what it should be 
    305305                  imskip1 = imask(ji,jj) * imask(ji+1,jj  )  ! 1 = should be connected 
    306306                  imskim1 = imask(ji,jj) * imask(ji-1,jj  )  ! 1 = should be connected 
     
    308308                  imskjm1 = imask(ji,jj) * imask(ji  ,jj-1)  ! 1 = should be connected 
    309309                  ! 
    310                   ! what it is ? ( 1 = no effective connection; jpk = effective connection ) 
     310                  ! what it is 
    311311                  imskip1_r=jpk ; imskim1_r=jpk; imskjp1_r=jpk; imskjm1_r=jpk 
    312312                  IF (misfdep(ji,jj) > imbathy(ji+1,jj  )) imskip1_r=1.0 ! 1 = no effective connection 
     
    316316                  ! 
    317317                  ! defining level needed for connectivity 
    318                   ! imskip1 * imskip1_r == 1   means    connection need to be enforce 
    319                   ! imskip1 * imskip1_r >= jpk means no connection need to be enforce 
     318                  ! imskip1 * imskip1_r == 1 means connections need to be enforce 
    320319                  jk=MIN(imbathy(ji+1,jj  ) * imskip1_r * imskip1, & 
    321320                     &   imbathy(ji-1,jj  ) * imskim1_r * imskim1, & 
    322321                     &   imbathy(ji  ,jj+1) * imskjp1_r * imskjp1, & 
    323322                     &   imbathy(ji  ,jj-1) * imskjm1_r * imskjm1, & 
    324                      &   jpk ) ! add jpk in the MIN to avoid out of boundary later on 
     323                     &   jpk+1 ) ! add jpk in the MIN to avoid out of boundary later on 
    325324                  ! 
    326325                  ! if connectivity is OK or no connection needed (grounding line) or grounded, zmisfdep=misfdep 
  • utils/tools/DOMAINcfg/src/dommsk.F90

    r14199 r14623  
    9898      !!--------------------------------------------------------------------- 
    9999      ! 
    100       REWIND( numnam_ref )              ! Namelist namlbc in reference namelist : Lateral momentum boundary condition 
     100    !  REWIND( numnam_ref )              ! Namelist namlbc in reference namelist : Lateral momentum boundary condition 
    101101      READ  ( numnam_ref, namlbc, IOSTAT = ios, ERR = 901 ) 
    102 901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namlbc in reference namelist', lwp ) 
    103       REWIND( numnam_cfg )              ! Namelist namlbc in configuration namelist : Lateral momentum boundary condition 
     102901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namlbc in reference namelist') 
     103    !  REWIND( numnam_cfg )              ! Namelist namlbc in configuration namelist : Lateral momentum boundary condition 
    104104      READ  ( numnam_cfg, namlbc, IOSTAT = ios, ERR = 902 ) 
    105 902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namlbc in configuration namelist', lwp ) 
     105902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namlbc in configuration namelist') 
    106106      IF(lwm) WRITE ( numond, namlbc ) 
    107107       
     
    156156            END DO   
    157157         END DO   
    158       ELSE 
     158         ELSE 
    159159         DO jk = 1, jpk 
    160160            DO jj = 1, jpj 
     
    209209      ! -------------------- 
    210210      ! 
    211       iif = nn_hls   ;   iil = nlci - nn_hls + 1 
    212       ijf = nn_hls   ;   ijl = nlcj - nn_hls + 1 
     211      iif = nn_hls   ;   iil = jpi - nn_hls + 1 
     212      ijf = nn_hls   ;   ijl = jpj - nn_hls + 1 
    213213      ! 
    214214      !                          ! halo mask : 0 on the halo and 1 elsewhere 
     
    225225         tpol(jpiglo/2+1:jpiglo) = 0._wp 
    226226         fpol(     1    :jpiglo) = 0._wp 
    227          IF( mjg(nlej) == jpjglo ) THEN                  ! only half of the nlcj-1 row for tmask_h 
     227         IF( mjg(Nje0) == jpjglo ) THEN                  ! only half of the nlcj-1 row for tmask_h 
    228228            DO ji = iif+1, iil-1 
    229                tmask_h(ji,nlej-1) = tmask_h(ji,nlej-1) * tpol(mig(ji)) 
     229               tmask_h(ji,Nje0-1) = tmask_h(ji,Nje0-1) * tpol(mig(ji)) 
    230230            END DO 
    231231         ENDIF 
     
    275275#if defined key_agrif  
    276276            IF( .NOT. AGRIF_Root() ) THEN  
    277                IF(lk_east)  fmask(nlci-1 , :     ,jk) = 0.e0      ! east  
     277               IF(lk_east)  fmask(jpi-1 , :     ,jk) = 0.e0      ! east  
    278278               IF(lk_west)  fmask(1      , :     ,jk) = 0.e0      ! west  
    279                IF(lk_north) fmask(:      ,nlcj-1 ,jk) = 0.e0      ! north  
     279               IF(lk_north) fmask(:      ,jpj-1 ,jk) = 0.e0      ! north  
    280280               IF(lk_south) fmask(:      ,1      ,jk) = 0.e0      ! south  
    281281            ENDIF  
     
    294294      ! --------------------------------  
    295295      ! 
    296       ! write mesh mask 
    297       IF ( nn_msh > 0 ) CALL dom_wri 
    298       ! 
     296 
    299297      CALL usr_def_fmask( cp_cfg, jp_cfg, fmask ) 
    300298      ! 
  • utils/tools/DOMAINcfg/src/domngb.F90

    r14199 r14623  
    4646      INTEGER :: ik         ! working level 
    4747      INTEGER , DIMENSION(2) ::   iloc 
     48      REAL(wp)               ::   zlon, zmini 
    4849      REAL(wp), DIMENSION(jpi,jpj) ::   zglam, zgphi, zmask, zdist 
    4950      !!-------------------------------------------------------------------- 
     
    5354      IF ( PRESENT(kkk) ) ik=kkk 
    5455      SELECT CASE( cdgrid ) 
    55       CASE( 'U' )  ; zglam(:,:) = glamu(:,:) ; zgphi(:,:) = gphiu(:,:) ; zmask(nldi:nlei,nldj:nlej) = umask(nldi:nlei,nldj:nlej,ik) 
    56       CASE( 'V' )  ; zglam(:,:) = glamv(:,:) ; zgphi(:,:) = gphiv(:,:) ; zmask(nldi:nlei,nldj:nlej) = vmask(nldi:nlei,nldj:nlej,ik) 
    57       CASE( 'F' )  ; zglam(:,:) = glamf(:,:) ; zgphi(:,:) = gphif(:,:) ; zmask(nldi:nlei,nldj:nlej) = fmask(nldi:nlei,nldj:nlej,ik) 
    58       CASE DEFAULT ; zglam(:,:) = glamt(:,:) ; zgphi(:,:) = gphit(:,:) ; zmask(nldi:nlei,nldj:nlej) = tmask(nldi:nlei,nldj:nlej,ik) 
     56      CASE( 'U' )  ; zglam(:,:) = glamu(:,:) ; zgphi(:,:) = gphiu(:,:) ; zmask(Nis0:Nie0,Njs0:Nje0) = umask(Nis0:Nie0,Njs0:Nje0,ik) 
     57      CASE( 'V' )  ; zglam(:,:) = glamv(:,:) ; zgphi(:,:) = gphiv(:,:) ; zmask(Nis0:Nie0,Njs0:Nje0) = vmask(Nis0:Nie0,Njs0:Nje0,ik) 
     58      CASE( 'F' )  ; zglam(:,:) = glamf(:,:) ; zgphi(:,:) = gphif(:,:) ; zmask(Nis0:Nie0,Njs0:Nje0) = fmask(Nis0:Nie0,Njs0:Nje0,ik) 
     59      CASE DEFAULT ; zglam(:,:) = glamt(:,:) ; zgphi(:,:) = gphit(:,:) ; zmask(Nis0:Nie0,Njs0:Nje0) = tmask(Nis0:Nie0,Njs0:Nje0,ik) 
    5960      END SELECT 
    6061 
    61       zdist = dist(plon, plat, zglam, zgphi) 
     62      zlon       = MOD( plon       + 720., 360. )                                     ! plon between    0 and 360 
     63      zglam(:,:) = MOD( zglam(:,:) + 720., 360. )                                     ! glam between    0 and 360 
     64      IF( zlon > 270. )   zlon = zlon - 360.                                          ! zlon between  -90 and 270 
     65      IF( zlon <  90. )   WHERE( zglam(:,:) > 180. ) zglam(:,:) = zglam(:,:) - 360.   ! glam between -180 and 180 
     66      zglam(:,:) = zglam(:,:) - zlon 
    6267 
    6368      IF( lk_mpp ) THEN   
  • utils/tools/DOMAINcfg/src/domwri.F90

    r14199 r14623  
    215215      lldbl(:,:,1) = puniq(:,:) == ztstref(:,:)   ! check which values have been changed  
    216216      ! 
    217       puniq(:,:) = REAL( COUNT( lldbl(:,:,:), dim = 3 ) , wp ) 
     217      puniq(:,:) = 1.                             ! default definition 
     218      ! fill only the inner part of the cpu with llbl converted into real  
     219      puniq(Nis0:Nie0,Njs0:Nje0) = REAL( COUNT( lldbl(Nis0:Nie0,Njs0:Nje0,:), dim = 3 ) , wp ) 
    218220      ! 
    219221   END SUBROUTINE dom_uniq 
  • utils/tools/DOMAINcfg/src/domzgr.F90

    r13390 r14623  
    7575   REAL(wp) ::   rn_zb_b           !  offset for calculating Zb 
    7676 
    77   !! * Substitutions 
     77   !! * Substitutions 
     78#  include "do_loop_substitute.h90" 
    7879   !!---------------------------------------------------------------------- 
    79    !!                   ***  vectopt_loop_substitute  *** 
    80    !!---------------------------------------------------------------------- 
    81    !! ** purpose :   substitute the inner loop start/end indices with CPP macro 
    82    !!                allow unrolling of do-loop (useful with vector processors) 
    83    !!---------------------------------------------------------------------- 
    84    !!---------------------------------------------------------------------- 
    85    !! NEMO/OPA 3.7 , NEMO Consortium (2014) 
    86    !! $Id: vectopt_loop_substitute.h90 4990 2014-12-15 16:42:49Z timgraham $  
    87    !! Software governed by the CeCILL licence (./LICENSE) 
    88    !!---------------------------------------------------------------------- 
    89    !!---------------------------------------------------------------------- 
    90    !! NEMO/OPA 3.3.1 , NEMO Consortium (2011) 
    91    !! $Id: domzgr.F90 6827 2016-08-01 13:37:15Z flavoni $ 
    92    !! Software governed by the CeCILL licence     (./LICENSE) 
     80   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     81   !! $Id: dommsk.F90 13305 2020-07-14 17:12:25Z acc $ 
     82   !! Software governed by the CeCILL license (see ./LICENSE) 
    9383   !!---------------------------------------------------------------------- 
    9484CONTAINS        
     
    124114      ! 
    125115      ! 
    126       REWIND( numnam_ref )              ! Namelist namzgr in reference namelist : Vertical coordinate 
     116     ! REWIND( numnam_ref )              ! Namelist namzgr in reference namelist : Vertical coordinate 
    127117      READ  ( numnam_ref, namzgr, IOSTAT = ios, ERR = 901 ) 
    128 901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr in reference namelist', lwp ) 
    129  
    130       REWIND( numnam_cfg )              ! Namelist namzgr in configuration namelist : Vertical coordinate 
     118901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr in reference namelist') 
     119 
     120     ! REWIND( numnam_cfg )              ! Namelist namzgr in configuration namelist : Vertical coordinate 
    131121      READ  ( numnam_cfg, namzgr, IOSTAT = ios, ERR = 902 ) 
    132 902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr in configuration namelist', lwp ) 
     122902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr in configuration namelist') 
    133123      IF(lwm) WRITE ( numond, namzgr ) 
    134124 
     
    279269      CALL iom_get( inum, jpdom_unknown, 'e3w_1d'  , pe3w_1d  ) 
    280270      ! 
    281       CALL iom_get( inum, jpdom_data, 'e3t_0'  , pe3t  , lrowattr=ln_use_jattr )    ! 3D coordinate 
    282       CALL iom_get( inum, jpdom_data, 'e3u_0'  , pe3u  , lrowattr=ln_use_jattr ) 
    283       CALL iom_get( inum, jpdom_data, 'e3v_0'  , pe3v  , lrowattr=ln_use_jattr ) 
    284       CALL iom_get( inum, jpdom_data, 'e3f_0'  , pe3f  , lrowattr=ln_use_jattr ) 
    285       CALL iom_get( inum, jpdom_data, 'e3w_0'  , pe3w  , lrowattr=ln_use_jattr ) 
    286       CALL iom_get( inum, jpdom_data, 'e3uw_0' , pe3uw , lrowattr=ln_use_jattr ) 
    287       CALL iom_get( inum, jpdom_data, 'e3vw_0' , pe3vw , lrowattr=ln_use_jattr ) 
     271      CALL iom_get( inum, jpdom_global, 'e3t_0'  , pe3t , cd_type = 'T', psgn = 1._wp, kfill = jpfillcopy )    ! 3D coordinate 
     272      CALL iom_get( inum, jpdom_global, 'e3u_0'  , pe3u , cd_type = 'U', psgn = 1._wp, kfill = jpfillcopy ) 
     273      CALL iom_get( inum, jpdom_global, 'e3v_0'  , pe3v , cd_type = 'V', psgn = 1._wp, kfill = jpfillcopy ) 
     274      CALL iom_get( inum, jpdom_global, 'e3f_0'  , pe3f , cd_type = 'F', psgn = 1._wp, kfill = jpfillcopy ) 
     275      CALL iom_get( inum, jpdom_global, 'e3w_0'  , pe3w , cd_type = 'W', psgn = 1._wp, kfill = jpfillcopy ) 
     276      CALL iom_get( inum, jpdom_global, 'e3uw_0' , pe3uw, cd_type = 'U', psgn = 1._wp, kfill = jpfillcopy ) 
     277      CALL iom_get( inum, jpdom_global, 'e3vw_0' , pe3vw, cd_type = 'V', psgn = 1._wp, kfill = jpfillcopy ) 
    288278      ! 
    289279      !                          !* depths 
     
    297287         CALL iom_get( inum, jpdom_unknown, 'gdept_1d', pdept_1d )    
    298288         CALL iom_get( inum, jpdom_unknown, 'gdepw_1d', pdepw_1d ) 
    299          CALL iom_get( inum, jpdom_data   , 'gdept_0' , pdept , lrowattr=ln_use_jattr ) 
    300          CALL iom_get( inum, jpdom_data   , 'gdepw_0' , pdepw , lrowattr=ln_use_jattr ) 
     289         CALL iom_get( inum, jpdom_global , 'gdept_0' , pdept, kfill = jpfillcopy ) 
     290         CALL iom_get( inum, jpdom_global , 'gdepw_0' , pdepw, kfill = jpfillcopy ) 
    301291         ! 
    302292      ELSE                                !- depths computed from e3. scale factors 
     
    312302      ! 
    313303      !                          !* ocean top and bottom level 
    314       CALL iom_get( inum, jpdom_data, 'top_level'    , z2d  , lrowattr=ln_use_jattr )   ! 1st wet T-points (ISF) 
     304      CALL iom_get( inum, jpdom_global, 'top_level'    , z2d )   ! 1st wet T-points (ISF) 
    315305      k_top(:,:) = NINT( z2d(:,:) ) 
    316       CALL iom_get( inum, jpdom_data, 'bottom_level' , z2d  , lrowattr=ln_use_jattr )   ! last wet T-points 
     306      CALL iom_get( inum, jpdom_global, 'bottom_level' , z2d )   ! last wet T-points 
    317307      k_bot(:,:) = NINT( z2d(:,:) ) 
    318308      ! 
     
    660650         mbathy(:,:) = 0                                   ! set to zero extra halo points 
    661651         bathy (:,:) = 0._wp                               ! (require for mpp case) 
    662          DO jj = 1, nlcj                                   ! interior values 
    663             DO ji = 1, nlci 
     652         DO_2D( 0, 0, 0, 0 ) 
    664653               mbathy(ji,jj) = idta( mig(ji), mjg(jj) ) 
    665654               bathy (ji,jj) = zdta( mig(ji), mjg(jj) ) 
    666             END DO 
    667          END DO 
     655         END_2D 
    668656         risfdep(:,:)=0.e0 
    669657         misfdep(:,:)=1 
     
    677665         IF( ln_zco )   THEN                          ! zco : read level bathymetry  
    678666            CALL iom_open ( cn_topolvl, inum )   
    679             CALL iom_get  ( inum, jpdom_data, cn_bathlvl, bathy ) 
     667            CALL iom_get  ( inum, jpdom_auto, cn_bathlvl, bathy ) 
    680668            CALL iom_close( inum ) 
    681669            mbathy(:,:) = INT( bathy(:,:) ) 
     
    715703            IF( ntopo == 1) THEN 
    716704               CALL iom_open ( cn_topo, inum )  
    717                CALL iom_get  ( inum, jpdom_data, cn_bath, bathy, lrowattr=ln_use_jattr ) 
     705               CALL iom_get  ( inum, jpdom_auto, cn_bath, bathy ) 
    718706               CALL iom_close( inum ) 
    719707            ELSE 
     
    735723            IF ( ln_isfcav ) THEN 
    736724               CALL iom_open ( cn_fisfd, inum )  
    737                CALL iom_get  ( inum, jpdom_data, cn_visfd, risfdep ) 
     725               CALL iom_get  ( inum, jpdom_auto, cn_visfd, risfdep ) 
    738726               CALL iom_close( inum ) 
    739727            END IF 
     
    857845      ENDIF 
    858846      !                                          ! East-west cyclic boundary conditions 
     847 
    859848      IF( jperio == 0 ) THEN 
    860849         IF(lwp) WRITE(numout,*) ' mbathy set to 0 along east and west boundary: jperio = ', jperio 
    861          IF( lk_mpp ) THEN 
    862             IF( nbondi == -1 .OR. nbondi == 2 ) THEN 
    863                IF( jperio /= 1 )   mbathy(1,:) = 0 
    864             ENDIF 
    865             IF( nbondi == 1 .OR. nbondi == 2 ) THEN 
    866                IF( jperio /= 1 )   mbathy(nlci,:) = 0 
    867             ENDIF 
     850         IF( ln_zco .OR. ln_zps ) THEN 
     851           mbathy(  mi0(     1+nn_hls):mi1(     1+nn_hls),:) = 0 
     852           mbathy(  mi0(jpiglo-nn_hls):mi1(jpiglo-nn_hls),:) = 0 
    868853         ELSE 
    869             IF( ln_zco .OR. ln_zps ) THEN 
    870                mbathy( 1 ,:) = 0 
    871                mbathy(jpi,:) = 0 
    872             ELSE 
    873                mbathy( 1 ,:) = jpkm1 
    874                mbathy(jpi,:) = jpkm1 
    875             ENDIF 
     854           mbathy(  mi0(     1+nn_hls):mi1(     1+nn_hls),:) = jpkm1 
     855           mbathy(  mi0(jpiglo-nn_hls):mi1(jpiglo-nn_hls),:) = jpkm1 
    876856         ENDIF 
    877857      ELSEIF( l_Iperio ) THEN 
     
    898878      ! Number of ocean level inferior or equal to jpkm1 
    899879      zbathy(:,:) = FLOAT( mbathy(:,:) ) 
    900       ikmax = glob_max( 'domzgr', zbathy(:,:) ) 
     880      ikmax = MAXVAL(zbathy(:,:)) 
     881      CALL mpp_max( 'domzgr',ikmax) 
    901882 
    902883      IF( ikmax > jpkm1 ) THEN 
     
    13081289      ALLOCATE( zenv(jpi,jpj), ztmp(jpi,jpj), zmsk(jpi,jpj), zri(jpi,jpj), zrj(jpi,jpj), zhbat(jpi,jpj) , ztmpi1(jpi,jpj), ztmpi2(jpi,jpj), ztmpj1(jpi,jpj), ztmpj2(jpi,jpj) ) 
    13091290      ! 
    1310       REWIND( numnam_ref )              ! Namelist namzgr_sco in reference namelist : Sigma-stretching parameters 
     1291      !REWIND( numnam_ref )              ! Namelist namzgr_sco in reference namelist : Sigma-stretching parameters 
    13111292      READ  ( numnam_ref, namzgr_sco, IOSTAT = ios, ERR = 901) 
    1312 901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_sco in reference namelist', lwp ) 
    1313  
    1314       REWIND( numnam_cfg )              ! Namelist namzgr_sco in configuration namelist : Sigma-stretching parameters 
     1293901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_sco in reference namelist') 
     1294 
     1295      !REWIND( numnam_cfg )              ! Namelist namzgr_sco in configuration namelist : Sigma-stretching parameters 
    13151296      READ  ( numnam_cfg, namzgr_sco, IOSTAT = ios, ERR = 902 ) 
    1316 902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_sco in configuration namelist', lwp ) 
     1297902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzgr_sco in configuration namelist') 
    13171298      IF(lwm) WRITE ( numond, namzgr_sco ) 
    13181299 
     
    13861367 
    13871368      ! apply lateral boundary condition   CAUTION: keep the value when the lbc field is zero 
    1388       CALL lbc_lnk( 'domzgr',zenv, 'T', 1._wp, 'no0' ) 
     1369      CALL lbc_lnk( 'domzgr',zenv, 'T', 1._wp, kfillmode=jpfillnothing ) 
    13891370      !  
    13901371      ! smooth the bathymetry (if required) 
     
    14171398         ! we could exit DO WHILE prematurely before checking r-value 
    14181399         ! of current zenv 
    1419          DO jj = 1, nlcj 
    1420             DO ji = 1, nlci 
     1400          DO_2D( 0, 0, 0, 0 ) 
    14211401               zrmax = MAX( zrmax, ABS(zri(ji,jj)), ABS(zrj(ji,jj)) ) 
    1422             END DO 
    1423          END DO 
     1402         END_2D 
    14241403         zri(:,:) = 0._wp 
    14251404         zrj(:,:) = 0._wp 
    1426          DO jj = 1, nlcj 
    1427             DO ji = 1, nlci 
    1428                iip1 = MIN( ji+1, nlci )      ! force zri = 0 on last line (ji=ncli+1 to jpi) 
    1429                ijp1 = MIN( jj+1, nlcj )      ! force zrj = 0 on last raw  (jj=nclj+1 to jpj) 
     1405          DO_2D( 0, 0, 0, 0 ) 
     1406               iip1 = MIN( ji+1, jpi )      ! force zri = 0 on last line (ji=ncli+1 to jpi) 
     1407               ijp1 = MIN( jj+1, jpj )      ! force zrj = 0 on last raw  (jj=nclj+1 to jpj) 
    14301408               IF( (zenv(ji,jj) > 0._wp) .AND. (zenv(iip1,jj) > 0._wp)) THEN 
    14311409                  zri(ji,jj) = ( zenv(iip1,jj  ) - zenv(ji,jj) ) / ( zenv(iip1,jj  ) + zenv(ji,jj) ) 
     
    14381416               IF( zrj(ji,jj) >  rn_rmax )   ztmpj1(ji  ,jj  ) = zenv(ji  ,ijp1) * zrfact 
    14391417               IF( zrj(ji,jj) < -rn_rmax )   ztmpj2(ji  ,ijp1) = zenv(ji  ,jj  ) * zrfact 
    1440             END DO 
    1441          END DO 
     1418         END_2D 
    14421419  !       IF( lk_mpp )   CALL mpp_max( zrmax )   ! max over the global domain 
    14431420         ! 
    14441421         IF(lwp)WRITE(numout,*) 'zgr_sco :   iter= ',jl, ' rmax= ', zrmax 
    14451422         ! 
    1446          DO jj = 1, nlcj 
    1447             DO ji = 1, nlci 
     1423         DO_2D( 0, 0, 0, 0 ) 
    14481424               zenv(ji,jj) = MAX(zenv(ji,jj), ztmpi1(ji,jj), ztmpi2(ji,jj), ztmpj1(ji,jj), ztmpj2(ji,jj) ) 
    1449             END DO 
    1450          END DO 
     1425         END_2D 
    14511426         ! apply lateral boundary condition   CAUTION: keep the value when the lbc field is zero 
    1452          CALL lbc_lnk( 'toto',zenv, 'T', 1._wp, 'no0' ) 
     1427         CALL lbc_lnk( 'toto',zenv, 'T', 1._wp, kfillmode=jpfillnothing) 
    14531428         !                                                  ! ================ ! 
    14541429      END DO                                                !     End loop     ! 
  • utils/tools/DOMAINcfg/src/errioipsl.f90

    r6951 r14623  
    11MODULE errioipsl 
     2!$AGRIF_DO_NOT_TREAT 
    23!- 
    34!$Id: errioipsl.f90 2281 2010-10-15 14:21:13Z smasson $ 
     
    213214!=== 
    214215!------------------- 
     216!$AGRIF_END_DO_NOT_TREAT 
    215217END MODULE errioipsl 
  • utils/tools/DOMAINcfg/src/in_out_manager.F90

    r13204 r14623  
    2222   !!---------------------------------------------------------------------- 
    2323   CHARACTER(lc) ::   cn_exp           !: experiment name used for output filename 
     24   CHARACTER(lc) ::   cn_ocerst_in     !: suffix of ocean restart name (input) 
     25   CHARACTER(lc) ::   cn_ocerst_indir  !: restart input directory 
     26   CHARACTER(lc) ::   cn_ocerst_out    !: suffix of ocean restart name (output) 
     27   CHARACTER(lc) ::   cn_ocerst_outdir !: restart output directory 
     28   LOGICAL       ::   ln_rstart        !: start from (F) rest or (T) a restart file 
     29   LOGICAL       ::   ln_rst_list      !: output restarts at list of times (T) or by frequency (F) 
     30   INTEGER       ::   nn_rstctl        !: control of the time step (0, 1 or 2) 
     31   INTEGER       ::   nn_rstssh   = 0  !: hand made initilization of ssh or not (1/0) 
    2432   INTEGER       ::   nn_it000         !: index of the first time step 
    2533   INTEGER       ::   nn_itend         !: index of the last time step 
     
    2735   INTEGER       ::   nn_time0         !: initial time of day in hhmm 
    2836   INTEGER       ::   nn_leapy         !: Leap year calendar flag (0/1 or 30) 
     37   INTEGER       ::   nn_istate        !: initial state output flag (0/1) 
     38   INTEGER       ::   nn_write         !: model standard output frequency 
     39   INTEGER       ::   nn_stock         !: restart file frequency 
     40   INTEGER, DIMENSION(10) :: nn_stocklist  !: restart dump times 
    2941   LOGICAL       ::   ln_mskland       !: mask land points in NetCDF outputs (costly: + ~15%) 
    3042   LOGICAL       ::   ln_cfmeta        !: output additional data to netCDF files required for compliance with the CF metadata standard 
     
    3345   LOGICAL       ::   ln_xios_read     !: use xios to read single file restart 
    3446   INTEGER       ::   nn_wxios         !: write resart using xios 0 - no, 1 - single, 2 - multiple file output 
     47   INTEGER       ::   nn_no            !: Assimilation cycle 
    3548 
    3649#if defined key_netcdf4 
     
    6174 
    6275   CHARACTER(lc) ::   cexper                      !: experiment name used for output filename 
     76   INTEGER       ::   nrstdt                      !: control of the time step (0, 1 or 2) 
    6377   INTEGER       ::   nit000                      !: index of the first time step 
    6478   INTEGER       ::   nitend                      !: index of the last time step 
    6579   INTEGER       ::   ndate0                      !: initial calendar date aammjj 
    6680   INTEGER       ::   nleapy                      !: Leap year calendar flag (0/1 or 30) 
     81   INTEGER       ::   ninist                      !: initial state output flag (0/1) 
     82 
     83   !!---------------------------------------------------------------------- 
     84   !! was in restart but moved here because of the OFF line... better solution should be found... 
     85   !!---------------------------------------------------------------------- 
     86   INTEGER ::   nitrst                !: time step at which restart file should be written 
     87   LOGICAL ::   lrst_oce              !: logical to control the oce restart write  
     88   LOGICAL ::   lrst_ice              !: logical to control the ice restart write  
     89   LOGICAL ::   lrst_abl              !: logical to control the abl restart write  
     90   INTEGER ::   numror = 0            !: logical unit for ocean restart (read). Init to 0 is needed for SAS (in daymod.F90) 
     91   INTEGER ::   numrir                !: logical unit for ice   restart (read) 
     92   INTEGER ::   numrar                !: logical unit for abl   restart (read) 
     93   INTEGER ::   numrow                !: logical unit for ocean restart (write) 
     94   INTEGER ::   numriw                !: logical unit for ice   restart (write) 
     95   INTEGER ::   numraw                !: logical unit for abl   restart (write) 
     96   INTEGER ::   nrst_lst              !: number of restart to output next 
     97 
     98   !!---------------------------------------------------------------------- 
     99   !!                    output monitoring 
     100   !!---------------------------------------------------------------------- 
     101   TYPE :: sn_ctl                !: structure for control over output selection 
     102      LOGICAL :: l_runstat = .FALSE.  !: Produce/do not produce run.stat file (T/F) 
     103      LOGICAL :: l_trcstat = .FALSE.  !: Produce/do not produce tracer.stat file (T/F) 
     104      LOGICAL :: l_oceout  = .FALSE.  !: Produce all ocean.outputs    (T) or just one (F) 
     105      LOGICAL :: l_layout  = .FALSE.  !: Produce all layout.dat files (T) or just one (F) 
     106      LOGICAL :: l_prtctl  = .FALSE.  !: Produce/do not produce mpp.output_XXXX files (T/F) 
     107      LOGICAL :: l_prttrc  = .FALSE.  !: Produce/do not produce mpp.top.output_XXXX files (T/F) 
     108      LOGICAL :: l_oasout  = .FALSE.  !: Produce/do not write oasis setup info to ocean.output (T/F) 
     109                                      !  Optional subsetting of processor report files 
     110                                      !  Default settings of 0/1000000/1 should ensure all areas report. 
     111                                      !  Set to a more restrictive range to select specific areas 
     112      INTEGER :: procmin   = 0        !: Minimum narea to output 
     113      INTEGER :: procmax   = 1000000  !: Maximum narea to output 
     114      INTEGER :: procincr  = 1        !: narea increment to output 
     115      INTEGER :: ptimincr  = 1        !: timestep increment to output (time.step and run.stat) 
     116   END TYPE 
     117   TYPE(sn_ctl), SAVE :: sn_cfctl     !: run control structure for selective output, must have SAVE for default init. of sn_ctl 
     118   LOGICAL ::   ln_timing        !: run control for timing 
     119   LOGICAL ::   ln_diacfl        !: flag whether to create CFL diagnostics 
     120   INTEGER ::   nn_ictls         !: Start i indice for the SUM control 
     121   INTEGER ::   nn_ictle         !: End   i indice for the SUM control 
     122   INTEGER ::   nn_jctls         !: Start j indice for the SUM control 
     123   INTEGER ::   nn_jctle         !: End   j indice for the SUM control 
     124   INTEGER ::   nn_isplt         !: number of processors following i 
     125   INTEGER ::   nn_jsplt         !: number of processors following j 
    67126 
    68127   !!---------------------------------------------------------------------- 
     
    74133   INTEGER ::   numnul          =   -1      !: logical unit for /dev/null 
    75134      !                                     !  early output can be collected; do not change 
    76    INTEGER ::   numnam_ref      =   -1      !: logical unit for reference namelist 
    77    INTEGER ::   numnam_cfg      =   -1      !: logical unit for configuration specific namelist 
    78135   INTEGER ::   numond          =   -1      !: logical unit for Output Namelist Dynamics 
    79136   INTEGER ::   numoni          =   -1      !: logical unit for Output Namelist Ice 
     137   INTEGER ::   numevo_ice      =   -1      !: logical unit for ice variables (temp. evolution) 
    80138   INTEGER ::   numrun          =   -1      !: logical unit for run statistics 
     139   INTEGER ::   numdct_in       =   -1      !: logical unit for transports computing 
     140   INTEGER ::   numdct_vol      =   -1      !: logical unit for volume transports output 
     141   INTEGER ::   numdct_heat     =   -1      !: logical unit for heat   transports output 
     142   INTEGER ::   numdct_salt     =   -1      !: logical unit for salt   transports output 
     143   INTEGER ::   numfl           =   -1      !: logical unit for floats ascii output 
     144   INTEGER ::   numflo          =   -1      !: logical unit for floats ascii output 
     145      ! 
     146   CHARACTER(LEN=:), ALLOCATABLE :: numnam_ref      !: character buffer for reference namelist 
     147   CHARACTER(LEN=:), ALLOCATABLE :: numnam_cfg      !: character buffer for configuration specific namelist 
     148   CHARACTER(LEN=:), ALLOCATABLE :: numnam_ice_ref  !: character buffer for ice reference namelist 
     149   CHARACTER(LEN=:), ALLOCATABLE :: numnam_ice_cfg  !: character buffer for ice configuration specific namelist 
    81150 
    82151   !!---------------------------------------------------------------------- 
     
    85154   INTEGER       ::   no_print = 0          !: optional argument of fld_fill (if present, suppress some control print) 
    86155   INTEGER       ::   nstop = 0             !: error flag (=number of reason for a premature stop run) 
     156!$AGRIF_DO_NOT_TREAT 
     157   INTEGER       ::   ngrdstop = -1         !: grid number having nstop > 1 
     158!$AGRIF_END_DO_NOT_TREAT 
    87159   INTEGER       ::   nwarn = 0             !: warning flag (=number of warning found during the run) 
    88160   CHARACTER(lc) ::   ctmp1, ctmp2, ctmp3   !: temporary characters 1 to 3 
     
    90162   CHARACTER(lc) ::   ctmp7, ctmp8, ctmp9   !: temporary characters 7 to 9 
    91163   CHARACTER(lc) ::   ctmp10                !: temporary character 10 
    92    CHARACTER(lc) ::   cform_err = "(/,' ===>>> : E R R O R',     /,'         ===========',/)"       !: 
    93    CHARACTER(lc) ::   cform_war = "(/,' ===>>> : W A R N I N G', /,'         ===============',/)"   !: 
    94164   LOGICAL       ::   lwm      = .FALSE.    !: boolean : true on the 1st processor only (always) 
    95    LOGICAL       ::   lwp      = .FALSE.    !: boolean : true on the 1st processor only .OR. ln_ctl 
     165   LOGICAL       ::   lwp      = .FALSE.    !: boolean : true on the 1st processor only .OR. sn_cfctl%l_oceout=T 
     166   LOGICAL       ::   lsp_area = .TRUE.     !: to make a control print over a specific area 
    96167   CHARACTER(lc) ::   cxios_context         !: context name used in xios 
    97168   CHARACTER(lc) ::   crxios_context         !: context name used in xios to read restart 
    98169   CHARACTER(lc) ::   cwxios_context        !: context name used in xios to write restart file 
    99170 
     171   !! * Substitutions 
     172#  include "do_loop_substitute.h90" 
    100173   !!---------------------------------------------------------------------- 
    101174   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    102    !! $Id: in_out_manager.F90 10570 2019-01-24 15:14:49Z acc $ 
     175   !! $Id: in_out_manager.F90 13286 2020-07-09 15:48:29Z smasson $ 
    103176   !! Software governed by the CeCILL license (see ./LICENSE) 
    104177   !!===================================================================== 
  • utils/tools/DOMAINcfg/src/ioipsl.f90

    r13204 r14623  
    11MODULE ioipsl 
     2!$AGRIF_DO_NOT_TREAT 
    23! 
    34!$Id: ioipsl.f90 2281 2010-10-15 14:21:13Z smasson $ 
     
    67! See IOIPSL/IOIPSL_License_CeCILL.txt 
    78! 
    8   USE errioipsl    
     9  USE errioipsl  
     10  USE stringop 
     11  USE mathelp     
     12  USE getincom 
    913  USE calendar    
    10   USE stringop 
    11  
     14  USE fliocom     
     15  USE flincom     
     16  USE histcom     
     17  USE restcom 
     18!$AGRIF_END_DO_NOT_TREAT 
    1219END MODULE ioipsl 
  • utils/tools/DOMAINcfg/src/iom.F90

    r14243 r14623  
    2121   !!---------------------------------------------------------------------- 
    2222   USE dom_oce         ! ocean space and time domain 
     23   USE domutl          !  
     24   !USE c1d             ! 1D vertical configuration 
     25   !USE flo_oce         ! floats module declarations 
    2326   USE lbclnk          ! lateal boundary condition / mpp exchanges 
    2427   USE iom_def         ! iom variables definitions 
     
    2629   USE in_out_manager  ! I/O manager 
    2730   USE lib_mpp           ! MPP library 
    28 #if defined key_xios 
    29    USE sbc_oce  , ONLY :   nn_fsbc         ! ocean space and time domain 
    30    USE trc_oce  , ONLY :   nn_dttrc        !  !: frequency of step on passive tracers 
     31#if defined key_iomput 
     32   USE sbc_oce  , ONLY :   nn_fsbc, ght_abl, ghw_abl, e3t_abl, e3w_abl, jpka, jpkam1 
    3133   USE icb_oce  , ONLY :   nclasses, class_num       !  !: iceberg classes 
    3234#if defined key_si3 
    3335   USE ice      , ONLY :   jpl 
    3436#endif 
    35    USE domngb          ! ocean space and time domain 
    3637   USE phycst          ! physical constants 
     38   USE dianam          ! build name of file 
    3739   USE xios 
    3840# endif 
    3941   USE ioipsl, ONLY :  ju2ymds    ! for calendar 
     42  ! USE crs             ! Grid coarsening 
    4043#if defined key_top 
    4144   USE trc, ONLY    :  profsed 
    4245#endif 
    4346   USE lib_fortran  
     47   !USE diu_bulk, ONLY : ln_diurnal_only, ln_diurnal 
    4448 
    4549   IMPLICIT NONE 
    4650   PUBLIC   !   must be public to be able to access iom_def through iom 
    4751    
    48 #if defined key_xios 
     52#if defined key_iomput 
    4953   LOGICAL, PUBLIC, PARAMETER ::   lk_iomput = .TRUE.        !: iom_put flag 
    5054#else 
    5155   LOGICAL, PUBLIC, PARAMETER ::   lk_iomput = .FALSE.       !: iom_put flag 
    5256#endif 
    53    PUBLIC iom_init, iom_swap, iom_open, iom_close, iom_setkt, iom_varid, iom_get 
     57   PUBLIC iom_init, iom_init_closedef, iom_swap, iom_open, iom_close, iom_setkt, iom_varid, iom_get, iom_get_var 
    5458   PUBLIC iom_chkatt, iom_getatt, iom_putatt, iom_getszuld, iom_rstput, iom_delay_rst, iom_put 
    55    PUBLIC iom_use, iom_context_finalize 
    56  
    57    PRIVATE iom_rp0d, iom_rp1d, iom_rp2d, iom_rp3d 
    58    PRIVATE iom_g0d, iom_g1d, iom_g2d, iom_g3d, iom_get_123d 
    59    PRIVATE iom_p1d, iom_p2d, iom_p3d 
    60 #if defined key_xios 
     59   PUBLIC iom_use, iom_context_finalize, iom_update_file_name, iom_miss_val 
     60 
     61   PRIVATE iom_rp0d_sp, iom_rp1d_sp, iom_rp2d_sp, iom_rp3d_sp 
     62   PRIVATE iom_rp0d_dp, iom_rp1d_dp, iom_rp2d_dp, iom_rp3d_dp 
     63   PRIVATE iom_get_123d 
     64   PRIVATE iom_g0d_sp, iom_g1d_sp, iom_g2d_sp, iom_g3d_sp 
     65   PRIVATE iom_g0d_dp, iom_g1d_dp, iom_g2d_dp, iom_g3d_dp 
     66   PRIVATE iom_p1d_sp, iom_p2d_sp, iom_p3d_sp, iom_p4d_sp 
     67   PRIVATE iom_p1d_dp, iom_p2d_dp, iom_p3d_dp, iom_p4d_dp 
     68#if defined key_iomput 
    6169   PRIVATE iom_set_domain_attr, iom_set_axis_attr, iom_set_field_attr, iom_set_file_attr, iom_get_file_attr, iom_set_grid_attr 
    62    PRIVATE set_grid, set_grid_bounds, set_scalar, set_xmlatt, set_mooring, iom_update_file_name, iom_sdate 
     70   PRIVATE set_grid, set_grid_bounds, set_scalar, set_xmlatt, set_mooring, iom_sdate 
    6371   PRIVATE iom_set_rst_context, iom_set_rstw_active, iom_set_rstr_active 
    6472# endif 
    65    PUBLIC iom_set_rstw_var_active, iom_set_rst_vars 
     73   PUBLIC iom_set_rstw_var_active, iom_set_rstw_core, iom_set_rst_vars 
    6674 
    6775   INTERFACE iom_get 
    68       MODULE PROCEDURE iom_g0d, iom_g1d, iom_g2d, iom_g3d 
     76      MODULE PROCEDURE iom_g0d_sp, iom_g1d_sp, iom_g2d_sp, iom_g3d_sp 
     77      MODULE PROCEDURE iom_g0d_dp, iom_g1d_dp, iom_g2d_dp, iom_g3d_dp 
    6978   END INTERFACE 
    7079   INTERFACE iom_getatt 
     
    7584   END INTERFACE 
    7685   INTERFACE iom_rstput 
    77       MODULE PROCEDURE iom_rp0d, iom_rp1d, iom_rp2d, iom_rp3d 
     86      MODULE PROCEDURE iom_rp0d_sp, iom_rp1d_sp, iom_rp2d_sp, iom_rp3d_sp 
     87      MODULE PROCEDURE iom_rp0d_dp, iom_rp1d_dp, iom_rp2d_dp, iom_rp3d_dp 
    7888   END INTERFACE 
    7989   INTERFACE iom_put 
    80       MODULE PROCEDURE iom_p0d, iom_p1d, iom_p2d, iom_p3d 
     90      MODULE PROCEDURE iom_p0d_sp, iom_p1d_sp, iom_p2d_sp, iom_p3d_sp, iom_p4d_sp 
     91      MODULE PROCEDURE iom_p0d_dp, iom_p1d_dp, iom_p2d_dp, iom_p3d_dp, iom_p4d_dp 
    8192   END INTERFACE iom_put 
    8293   
     94   !! * Substitutions 
     95#  include "do_loop_substitute.h90" 
    8396   !!---------------------------------------------------------------------- 
    8497   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    85    !! $Id: iom.F90 10523 2019-01-16 09:36:03Z smasson $ 
     98   !! $Id: iom.F90 13295 2020-07-10 18:24:21Z acc $ 
    8699   !! Software governed by the CeCILL license (see ./LICENSE) 
    87100   !!---------------------------------------------------------------------- 
    88101CONTAINS 
    89102 
    90    SUBROUTINE iom_init( cdname, fname, ld_tmppatch )  
     103   SUBROUTINE iom_init( cdname, fname, ld_closedef )  
    91104      !!---------------------------------------------------------------------- 
    92105      !!                     ***  ROUTINE   *** 
     
    97110      CHARACTER(len=*),           INTENT(in)  :: cdname 
    98111      CHARACTER(len=*), OPTIONAL, INTENT(in)  :: fname 
    99       LOGICAL         , OPTIONAL, INTENT(in)  :: ld_tmppatch 
    100 #if defined key_xios 
     112      LOGICAL         , OPTIONAL, INTENT(in)  :: ld_closedef 
     113#if defined key_iomput 
    101114      ! 
    102115      TYPE(xios_duration) :: dtime    = xios_duration(0, 0, 0, 0, 0, 0) 
    103116      TYPE(xios_date)     :: start_date 
    104117      CHARACTER(len=lc) :: clname 
    105       INTEGER           :: ji, jkmin 
     118      INTEGER             :: irefyear, irefmonth, irefday 
     119      INTEGER           :: ji 
    106120      LOGICAL :: llrst_context              ! is context related to restart 
    107121      ! 
    108122      REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zt_bnds, zw_bnds 
    109       LOGICAL ::   ll_tmppatch = .TRUE.    !: seb: patch before we remove periodicity 
    110       INTEGER ::   nldi_save, nlei_save    !:      and close boundaries in output files 
    111       INTEGER ::   nldj_save, nlej_save    !: 
    112       !!---------------------------------------------------------------------- 
    113       ! 
    114       ! seb: patch before we remove periodicity and close boundaries in output files 
    115       IF( PRESENT(ld_tmppatch) ) THEN   ;   ll_tmppatch = ld_tmppatch 
    116       ELSE                              ;   ll_tmppatch = .TRUE. 
    117       ENDIF 
    118       IF ( ll_tmppatch ) THEN 
    119          nldi_save = nldi   ;   nlei_save = nlei 
    120          nldj_save = nldj   ;   nlej_save = nlej 
    121          IF( nimpp           ==      1 ) nldi = 1 
    122          IF( nimpp + jpi - 1 == jpiglo ) nlei = jpi 
    123          IF( njmpp           ==      1 ) nldj = 1 
    124          IF( njmpp + jpj - 1 == jpjglo ) nlej = jpj 
    125       ENDIF 
     123      REAL(wp), DIMENSION(2,jpkam1)         :: za_bnds   ! ABL vertical boundaries 
     124      LOGICAL ::   ll_closedef = .TRUE. 
     125      !!---------------------------------------------------------------------- 
     126      ! 
     127      IF ( PRESENT(ld_closedef) ) ll_closedef = ld_closedef 
    126128      ! 
    127129      ALLOCATE( zt_bnds(2,jpk), zw_bnds(2,jpk) ) 
     
    134136 
    135137      ! Calendar type is now defined in xml file  
     138      IF (.NOT.(xios_getvar('ref_year' ,irefyear ))) irefyear  = 1900 
     139      IF (.NOT.(xios_getvar('ref_month',irefmonth))) irefmonth = 01 
     140      IF (.NOT.(xios_getvar('ref_day'  ,irefday  ))) irefday   = 01 
     141 
    136142      SELECT CASE ( nleapy )        ! Choose calendar for IOIPSL 
    137       CASE ( 1)   ; CALL xios_define_calendar( TYPE = "Gregorian", time_origin = xios_date(1900,01,01,00,00,00), & 
    138           &                                    start_date = xios_date(nyear,nmonth,nday,0,0,0) ) 
    139       CASE ( 0)   ; CALL xios_define_calendar( TYPE = "NoLeap"   , time_origin = xios_date(1900,01,01,00,00,00), & 
    140           &                                    start_date = xios_date(nyear,nmonth,nday,0,0,0) ) 
    141       CASE (30)   ; CALL xios_define_calendar( TYPE = "D360"     , time_origin = xios_date(1900,01,01,00,00,00), & 
    142           &                                    start_date = xios_date(nyear,nmonth,nday,0,0,0) ) 
     143      CASE ( 1)   ;   CALL xios_define_calendar( TYPE = "Gregorian", time_origin = xios_date(irefyear,irefmonth,irefday,0,0,0),  & 
     144          &                                                          start_date  = xios_date(   nyear,   nmonth,   nday,0,0,0) ) 
     145      CASE ( 0)   ;   CALL xios_define_calendar( TYPE = "NoLeap"   , time_origin = xios_date(irefyear,irefmonth,irefday,0,0,0),  & 
     146          &                                                          start_date  = xios_date(   nyear,   nmonth,   nday,0,0,0) ) 
     147      CASE (30)   ;   CALL xios_define_calendar( TYPE = "D360"     , time_origin = xios_date(irefyear,irefmonth,irefday,0,0,0),  & 
     148          &                                                          start_date  = xios_date(   nyear,   nmonth,   nday,0,0,0) ) 
    143149      END SELECT 
    144150 
     
    154160         ! 
    155161         IF( ln_cfmeta ) THEN   ! Add additional grid metadata 
    156             CALL iom_set_domain_attr("grid_T", area = e1e2t(nldi:nlei, nldj:nlej)) 
    157             CALL iom_set_domain_attr("grid_U", area = e1e2u(nldi:nlei, nldj:nlej)) 
    158             CALL iom_set_domain_attr("grid_V", area = e1e2v(nldi:nlei, nldj:nlej)) 
    159             CALL iom_set_domain_attr("grid_W", area = e1e2t(nldi:nlei, nldj:nlej)) 
     162            CALL iom_set_domain_attr("grid_T", area = real( e1e2t(Nis0:Nie0, Njs0:Nje0), dp)) 
     163            CALL iom_set_domain_attr("grid_U", area = real( e1e2u(Nis0:Nie0, Njs0:Nje0), dp)) 
     164            CALL iom_set_domain_attr("grid_V", area = real( e1e2v(Nis0:Nie0, Njs0:Nje0), dp)) 
     165            CALL iom_set_domain_attr("grid_W", area = real( e1e2t(Nis0:Nie0, Njs0:Nje0), dp)) 
    160166            CALL set_grid_bounds( "T", glamf, gphif, glamt, gphit ) 
    161167            CALL set_grid_bounds( "U", glamv, gphiv, glamu, gphiu ) 
     
    177183         ! 
    178184         IF( ln_cfmeta .AND. .NOT. llrst_context) THEN   ! Add additional grid metadata 
    179             CALL iom_set_domain_attr("grid_T", area = e1e2t_crs(nldi:nlei, nldj:nlej)) 
    180             CALL iom_set_domain_attr("grid_U", area = e1u_crs(nldi:nlei, nldj:nlej) * e2u_crs(nldi:nlei, nldj:nlej)) 
    181             CALL iom_set_domain_attr("grid_V", area = e1v_crs(nldi:nlei, nldj:nlej) * e2v_crs(nldi:nlei, nldj:nlej)) 
    182             CALL iom_set_domain_attr("grid_W", area = e1e2t_crs(nldi:nlei, nldj:nlej)) 
     185            CALL iom_set_domain_attr("grid_T", area = real(e1e2t_crs(Nis0:Nie0, Njs0:Nje0), dp)) 
     186            CALL iom_set_domain_attr("grid_U", area = real(e1u_crs(Nis0:Nie0, Njs0:Nje0) * e2u_crs(Nis0:Nie0, Njs0:Nje0), dp)) 
     187            CALL iom_set_domain_attr("grid_V", area = real(e1v_crs(Nis0:Nie0, Njs0:Nje0) * e2v_crs(Nis0:Nie0, Njs0:Nje0), dp)) 
     188            CALL iom_set_domain_attr("grid_W", area = real(e1e2t_crs(Nis0:Nie0, Njs0:Nje0), dp)) 
    183189            CALL set_grid_bounds( "T", glamf_crs, gphif_crs, glamt_crs, gphit_crs ) 
    184190            CALL set_grid_bounds( "U", glamv_crs, gphiv_crs, glamu_crs, gphiu_crs ) 
     
    190196      ! vertical grid definition 
    191197      IF(.NOT.llrst_context) THEN 
    192           CALL iom_set_axis_attr( "deptht",  paxis = gdept_1d ) 
    193           CALL iom_set_axis_attr( "depthu",  paxis = gdept_1d ) 
    194           CALL iom_set_axis_attr( "depthv",  paxis = gdept_1d ) 
    195           CALL iom_set_axis_attr( "depthw",  paxis = gdepw_1d ) 
    196  
     198          CALL iom_set_axis_attr(  "deptht", paxis = gdept_1d ) 
     199          CALL iom_set_axis_attr(  "depthu", paxis = gdept_1d ) 
     200          CALL iom_set_axis_attr(  "depthv", paxis = gdept_1d ) 
     201          CALL iom_set_axis_attr(  "depthw", paxis = gdepw_1d ) 
     202 
     203          ! ABL 
     204          IF( .NOT. ALLOCATED(ght_abl) ) THEN   ! force definition for xml files (xios)  
     205             ALLOCATE( ght_abl(jpka), ghw_abl(jpka), e3t_abl(jpka), e3w_abl(jpka) )   ! default allocation needed by iom 
     206             ght_abl(:) = -1._wp   ;   ghw_abl(:) = -1._wp 
     207             e3t_abl(:) = -1._wp   ;   e3w_abl(:) = -1._wp 
     208          ENDIF 
     209          CALL iom_set_axis_attr( "ght_abl", ght_abl(2:jpka) ) 
     210          CALL iom_set_axis_attr( "ghw_abl", ghw_abl(2:jpka) ) 
     211           
    197212          ! Add vertical grid bounds 
    198           jkmin = MIN(2,jpk)  ! in case jpk=1 (i.e. sas2D) 
    199           zt_bnds(2,:        ) = gdept_1d(:) 
    200           zt_bnds(1,jkmin:jpk) = gdept_1d(1:jpkm1) 
    201           zt_bnds(1,1        ) = gdept_1d(1) - e3w_1d(1) 
    202           zw_bnds(1,:        ) = gdepw_1d(:) 
    203           zw_bnds(2,1:jpkm1  ) = gdepw_1d(jkmin:jpk) 
    204           zw_bnds(2,jpk:     ) = gdepw_1d(jpk) + e3t_1d(jpk) 
    205           CALL iom_set_axis_attr( "deptht", bounds=zw_bnds ) 
    206           CALL iom_set_axis_attr( "depthu", bounds=zw_bnds ) 
    207           CALL iom_set_axis_attr( "depthv", bounds=zw_bnds ) 
    208           CALL iom_set_axis_attr( "depthw", bounds=zt_bnds ) 
    209           ! 
    210 # if defined key_floats 
     213          zt_bnds(2,:      ) = gdept_1d(:) 
     214          zt_bnds(1,2:jpk  ) = gdept_1d(1:jpkm1) 
     215          zt_bnds(1,1      ) = gdept_1d(1) - e3w_1d(1) 
     216          zw_bnds(1,:      ) = gdepw_1d(:) 
     217          zw_bnds(2,1:jpkm1) = gdepw_1d(2:jpk) 
     218          zw_bnds(2,jpk:   ) = gdepw_1d(jpk) + e3t_1d(jpk) 
     219          CALL iom_set_axis_attr(  "deptht", bounds=zw_bnds ) 
     220          CALL iom_set_axis_attr(  "depthu", bounds=zw_bnds ) 
     221          CALL iom_set_axis_attr(  "depthv", bounds=zw_bnds ) 
     222          CALL iom_set_axis_attr(  "depthw", bounds=zt_bnds ) 
     223 
     224          ! ABL 
     225          za_bnds(1,:) = ghw_abl(1:jpkam1) 
     226          za_bnds(2,:) = ghw_abl(2:jpka  ) 
     227          CALL iom_set_axis_attr( "ght_abl", bounds=za_bnds ) 
     228          za_bnds(1,:) = ght_abl(2:jpka  ) 
     229          za_bnds(2,:) = ght_abl(2:jpka  ) + e3w_abl(2:jpka) 
     230          CALL iom_set_axis_attr( "ghw_abl", bounds=za_bnds ) 
     231 
    211232          CALL iom_set_axis_attr( "nfloat", (/ (REAL(ji,wp), ji=1,jpnfl) /) ) 
    212 # endif 
    213233# if defined key_si3 
    214234          CALL iom_set_axis_attr( "ncatice", (/ (REAL(ji,wp), ji=1,jpl) /) ) 
     
    217237# endif 
    218238#if defined key_top 
    219           CALL iom_set_axis_attr( "profsed", paxis = profsed ) 
     239          IF( ALLOCATED(profsed) ) CALL iom_set_axis_attr( "profsed", paxis = profsed ) 
    220240#endif 
    221241          CALL iom_set_axis_attr( "icbcla", class_num ) 
    222           CALL iom_set_axis_attr( "iax_20C", (/ REAL(20,wp) /) ) 
    223           CALL iom_set_axis_attr( "iax_28C", (/ REAL(28,wp) /) ) 
     242          CALL iom_set_axis_attr( "iax_20C", (/ REAL(20,wp) /) )   ! strange syntaxe and idea... 
     243          CALL iom_set_axis_attr( "iax_26C", (/ REAL(26,wp) /) )   ! strange syntaxe and idea... 
     244          CALL iom_set_axis_attr( "iax_28C", (/ REAL(28,wp) /) )   ! strange syntaxe and idea... 
     245          CALL iom_set_axis_attr( "basin"  , (/ (REAL(ji,wp), ji=1,5) /) ) 
    224246      ENDIF 
    225247      ! 
     
    241263      ENDIF 
    242264      ! 
    243       ! end file definition 
    244       dtime%second = rdt 
     265      ! set time step length 
     266      dtime%second = rn_Dt 
    245267      CALL xios_set_timestep( dtime ) 
     268      ! 
     269      ! conditional closure of context definition 
     270      IF ( ll_closedef ) CALL iom_init_closedef 
     271      ! 
     272      DEALLOCATE( zt_bnds, zw_bnds ) 
     273      ! 
     274#endif 
     275      ! 
     276   END SUBROUTINE iom_init 
     277 
     278   SUBROUTINE iom_init_closedef 
     279      !!---------------------------------------------------------------------- 
     280      !!            ***  SUBROUTINE iom_init_closedef  *** 
     281      !!---------------------------------------------------------------------- 
     282      !! 
     283      !! ** Purpose : Closure of context definition 
     284      !! 
     285      !!---------------------------------------------------------------------- 
     286 
     287#if defined key_iomput 
    246288      CALL xios_close_context_definition() 
    247289      CALL xios_update_calendar( 0 ) 
    248       ! 
    249       DEALLOCATE( zt_bnds, zw_bnds ) 
    250       ! 
    251       IF ( ll_tmppatch ) THEN 
    252          nldi = nldi_save   ;   nlei = nlei_save 
    253          nldj = nldj_save   ;   nlej = nlej_save 
    254       ENDIF 
    255 #endif 
    256       ! 
    257    END SUBROUTINE iom_init 
     290#else 
     291      IF( .FALSE. )   WRITE(numout,*) 'iom_init_closedef: should not see this'   ! useless statement to avoid compilation warnings 
     292#endif 
     293 
     294   END SUBROUTINE iom_init_closedef 
    258295 
    259296   SUBROUTINE iom_set_rstw_var_active(field) 
     
    268305   CHARACTER(LEN=256) :: clinfo    ! info character 
    269306 
    270 #if defined key_xios 
     307#if defined key_iomput 
    271308   llis_set = .FALSE. 
    272309 
     
    284321   ENDIF 
    285322#else 
    286         clinfo = 'iom_set_rstw_var_active: key_xios is needed to use XIOS restart read/write functionality' 
     323        clinfo = 'iom_set_rstw_var_active: key_iomput is needed to use XIOS restart read/write functionality' 
    287324        CALL ctl_stop('STOP', TRIM(clinfo)) 
    288325#endif 
     
    301338   CHARACTER(len=256) :: rst_file 
    302339 
    303 #if defined key_xios 
     340#if defined key_iomput 
    304341   TYPE(xios_field) :: field_hdl 
    305342   TYPE(xios_file) :: file_hdl 
     
    348385   END SUBROUTINE iom_set_rstr_active 
    349386 
     387   SUBROUTINE iom_set_rstw_core(cdmdl) 
     388      !!--------------------------------------------------------------------- 
     389      !!                   ***  SUBROUTINE  iom_set_rstw_core  *** 
     390      !! 
     391      !! ** Purpose :  set variables which are always in restart file  
     392      !!--------------------------------------------------------------------- 
     393   CHARACTER (len=*), INTENT (IN) :: cdmdl ! model OPA or SAS 
     394   CHARACTER(LEN=256)             :: clinfo    ! info character 
     395#if defined key_iomput 
     396   IF(cdmdl == "OPA") THEN 
     397!from restart.F90 
     398   CALL iom_set_rstw_var_active("rn_Dt") 
     399   IF ( .NOT. ln_diurnal_only ) THEN 
     400        CALL iom_set_rstw_var_active('ub'  ) 
     401        CALL iom_set_rstw_var_active('vb'  ) 
     402        CALL iom_set_rstw_var_active('tb'  ) 
     403        CALL iom_set_rstw_var_active('sb'  ) 
     404        CALL iom_set_rstw_var_active('sshb') 
     405        ! 
     406        CALL iom_set_rstw_var_active('un'  ) 
     407        CALL iom_set_rstw_var_active('vn'  ) 
     408        CALL iom_set_rstw_var_active('tn'  ) 
     409        CALL iom_set_rstw_var_active('sn'  ) 
     410        CALL iom_set_rstw_var_active('sshn') 
     411        CALL iom_set_rstw_var_active('rhop') 
     412      ENDIF 
     413      IF(ln_diurnal) CALL iom_set_rstw_var_active('Dsst') 
     414!from trasbc.F90 
     415         CALL iom_set_rstw_var_active('sbc_hc_b') 
     416         CALL iom_set_rstw_var_active('sbc_sc_b') 
     417   ENDIF 
     418#else 
     419        clinfo = 'iom_set_rstw_core: key_iomput is needed to use XIOS restart read/write functionality' 
     420        CALL ctl_stop('STOP', TRIM(clinfo)) 
     421#endif 
     422   END SUBROUTINE iom_set_rstw_core 
     423 
    350424   SUBROUTINE iom_set_rst_vars(fields) 
    351425      !!--------------------------------------------------------------------- 
     
    360434 
    361435        i = 0 
    362         i = i + 1; fields(i)%vname="rdt";            fields(i)%grid="grid_scalar" 
     436        i = i + 1; fields(i)%vname="rn_Dt";            fields(i)%grid="grid_scalar" 
    363437        i = i + 1; fields(i)%vname="un";             fields(i)%grid="grid_N_3D" 
    364438        i = i + 1; fields(i)%vname="ub";             fields(i)%grid="grid_N_3D" 
     
    476550!sets enabled = .TRUE. for each field in restart file 
    477551   CHARACTER(len=*) :: cdrst_file 
    478 #if defined key_xios 
     552#if defined key_iomput 
    479553   TYPE(xios_field) :: field_hdl 
    480554   TYPE(xios_file) :: file_hdl 
     
    531605!ld_rstr is true for restart context. There is no need to define grid for  
    532606!restart read, because it's read from file 
    533 #if defined key_xios 
     607#if defined key_iomput 
    534608   TYPE(xios_domaingroup)            :: domaingroup_hdl  
    535609   TYPE(xios_domain)                 :: domain_hdl  
     
    562636      !!--------------------------------------------------------------------- 
    563637      CHARACTER(len=*), INTENT(in) :: cdname 
    564 #if defined key_xios 
     638#if defined key_iomput 
    565639      TYPE(xios_context) :: nemo_hdl 
    566640 
     
    577651 
    578652 
    579    SUBROUTINE iom_open( cdname, kiomid, ldwrt, kdom, lagrif, ldstop, ldiof, kdlev ) 
     653   SUBROUTINE iom_open( cdname, kiomid, ldwrt, ldstop, ldiof, kdlev, cdcomp ) 
    580654      !!--------------------------------------------------------------------- 
    581655      !!                   ***  SUBROUTINE  iom_open  *** 
     
    586660      INTEGER         , INTENT(  out)           ::   kiomid   ! iom identifier of the opened file 
    587661      LOGICAL         , INTENT(in   ), OPTIONAL ::   ldwrt    ! open in write modeb          (default = .FALSE.) 
    588       INTEGER         , INTENT(in   ), OPTIONAL ::   kdom     ! Type of domain to be written (default = jpdom_local_noovlap) 
    589662      LOGICAL         , INTENT(in   ), OPTIONAL ::   ldstop   ! stop if open to read a non-existing file (default = .TRUE.) 
    590       LOGICAL         , INTENT(in   ), OPTIONAL ::   lagrif   ! add 1_ prefix for AGRIF (default = .TRUE. 
    591663      LOGICAL         , INTENT(in   ), OPTIONAL ::   ldiof    ! Interp On the Fly, needed for AGRIF (default = .FALSE.) 
    592664      INTEGER         , INTENT(in   ), OPTIONAL ::   kdlev    ! number of vertical levels 
     665      CHARACTER(len=3), INTENT(in   ), OPTIONAL ::   cdcomp   ! name of component calling iom_nf90_open 
    593666      ! 
    594667      CHARACTER(LEN=256)    ::   clname    ! the name of the file based on cdname [[+clcpu]+clcpu] 
     
    599672      LOGICAL               ::   llok      ! check the existence  
    600673      LOGICAL               ::   llwrt     ! local definition of ldwrt 
    601       LOGICAL               ::   llnoov    ! local definition to read overlap 
    602674      LOGICAL               ::   llstop    ! local definition of ldstop 
    603675      LOGICAL               ::   lliof     ! local definition of ldiof 
    604       LOGICAL               ::   llagrif   ! local definition of lagrif 
    605676      INTEGER               ::   icnt      ! counter for digits in clcpu (max = jpmax_digits) 
    606677      INTEGER               ::   iln, ils  ! lengths of character 
    607       INTEGER               ::   idom      ! type of domain 
    608678      INTEGER               ::   istop     !  
    609       INTEGER, DIMENSION(2,5) ::   idompar ! domain parameters:  
    610679      ! local number of points for x,y dimensions 
    611680      ! position of first local point for x,y dimensions 
     
    613682      ! start halo size for x,y dimensions 
    614683      ! end halo size for x,y dimensions 
    615       ! 
    616       INTEGER ::   nldi_save, nlei_save    !:patch before we remove periodicity and close boundaries in output files 
    617       INTEGER ::   nldj_save, nlej_save    !: 
    618       ! 
    619684      !--------------------------------------------------------------------- 
    620685      ! Initializations and control 
     
    623688      clinfo = '                    iom_open ~~~  ' 
    624689      istop = nstop 
    625  
    626       ! use patch to force the writing off periodicity and close boundaries 
    627       ! without this, issue in some model decomposition 
    628       ! seb: patch before we remove periodicity and close boundaries in output files 
    629       nldi_save = nldi   ;   nlei_save = nlei 
    630       nldj_save = nldj   ;   nlej_save = nlej 
    631       IF( nimpp           ==      1 ) nldi = 1 
    632       IF( nimpp + jpi - 1 == jpiglo ) nlei = jpi 
    633       IF( njmpp           ==      1 ) nldj = 1 
    634       IF( njmpp + jpj - 1 == jpjglo ) nlej = jpj 
    635  
    636690      ! if iom_open is called for the first time: initialize iom_file(:)%nfid to 0 
    637691      ! (could be done when defining iom_file in f95 but not in f90) 
     
    650704      ELSE                         ;   llstop = .TRUE. 
    651705      ENDIF 
    652       ! do we add agrif suffix 
    653       IF( PRESENT(lagrif) ) THEN   ;   llagrif = lagrif 
    654       ELSE                         ;   llagrif = .TRUE. 
    655       ENDIF 
    656706      ! are we using interpolation on the fly? 
    657707      IF( PRESENT(ldiof) ) THEN   ;   lliof = ldiof 
    658708      ELSE                        ;   lliof = .FALSE. 
    659709      ENDIF 
    660       ! do we read the overlap  
    661       ! ugly patch SM+JMM+RB to overwrite global definition in some cases 
    662       !llnoov = (jpni * jpnj ) == jpnij .AND. .NOT. lk_agrif 
    663       ! for domain_cfg, force to read the full domain 
    664       llnoov = .FALSE. 
    665710      ! create the file name by added, if needed, TRIM(Agrif_CFixed()) and TRIM(clsuffix) 
    666711      ! ============= 
    667712      clname   = trim(cdname) 
    668       IF ( .NOT. Agrif_Root() .AND. .NOT. lliof .AND. llagrif) THEN 
     713      IF ( .NOT. Agrif_Root() .AND. .NOT. lliof ) THEN 
    669714         iln    = INDEX(clname,'/')  
    670715         cltmpn = clname(1:iln) 
     
    702747         lxios_sini = .TRUE. 
    703748      ENDIF 
    704       IF( llwrt ) THEN 
    705          ! check the domain definition 
    706 ! JMM + SM: ugly patch before getting the new version of lib_mpp) 
    707 !         idom = jpdom_local_noovlap   ! default definition 
    708          IF( llnoov ) THEN   ;   idom = jpdom_local_noovlap   ! default definition 
    709          ELSE                ;   idom = jpdom_local_full      ! default definition 
    710          ENDIF 
    711          IF( PRESENT(kdom) )   idom = kdom 
    712          ! create the domain informations 
    713          ! ============= 
    714          SELECT CASE (idom) 
    715          CASE (jpdom_local_full) 
    716             idompar(:,1) = (/ jpi             , jpj              /) 
    717             idompar(:,2) = (/ nimpp           , njmpp            /) 
    718             idompar(:,3) = (/ nimpp + jpi - 1 , njmpp + jpj - 1  /) 
    719             idompar(:,4) = (/ nldi - 1        , nldj - 1         /) 
    720             idompar(:,5) = (/ jpi - nlei      , jpj - nlej       /) 
    721          CASE (jpdom_local_noextra) 
    722             idompar(:,1) = (/ nlci            , nlcj             /) 
    723             idompar(:,2) = (/ nimpp           , njmpp            /) 
    724             idompar(:,3) = (/ nimpp + nlci - 1, njmpp + nlcj - 1 /) 
    725             idompar(:,4) = (/ nldi - 1        , nldj - 1         /) 
    726             idompar(:,5) = (/ nlci - nlei     , nlcj - nlej      /) 
    727          CASE (jpdom_local_noovlap) 
    728             idompar(:,1) = (/ nlei  - nldi + 1, nlej  - nldj + 1 /) 
    729             idompar(:,2) = (/ nimpp + nldi - 1, njmpp + nldj - 1 /) 
    730             idompar(:,3) = (/ nimpp + nlei - 1, njmpp + nlej - 1 /) 
    731             idompar(:,4) = (/ 0               , 0                /) 
    732             idompar(:,5) = (/ 0               , 0                /) 
    733          CASE DEFAULT 
    734             CALL ctl_stop( TRIM(clinfo), 'wrong value of kdom, only jpdom_local* cases are accepted' ) 
    735          END SELECT 
    736       ENDIF 
    737749      ! Open the NetCDF file 
    738750      ! ============= 
     
    758770      ENDIF 
    759771      IF( istop == nstop ) THEN   ! no error within this routine 
    760          CALL iom_nf90_open( clname, kiomid, llwrt, llok, idompar, kdlev = kdlev ) 
    761       ENDIF 
    762  
    763       nldi = nldi_save   ;   nlei = nlei_save 
    764       nldj = nldj_save   ;   nlej = nlej_save 
     772         CALL iom_nf90_open( clname, kiomid, llwrt, llok, kdlev = kdlev, cdcomp = cdcomp ) 
     773      ENDIF 
    765774      ! 
    766775   END SUBROUTINE iom_open 
     
    781790      CHARACTER(LEN=100)    ::   clinfo    ! info character 
    782791      !--------------------------------------------------------------------- 
     792      ! 
     793      IF( iom_open_init == 0 )   RETURN   ! avoid to use iom_file(jf)%nfid that us not yet initialized 
    783794      ! 
    784795      clinfo = '                    iom_close ~~~  ' 
     
    808819 
    809820 
    810    FUNCTION iom_varid ( kiomid, cdvar, kdimsz, kndims, ldstop )   
     821   FUNCTION iom_varid ( kiomid, cdvar, kdimsz, kndims, lduld, ldstop )   
    811822      !!----------------------------------------------------------------------- 
    812823      !!                  ***  FUNCTION  iom_varid  *** 
     
    817828      CHARACTER(len=*)     , INTENT(in   )           ::   cdvar    ! name of the variable 
    818829      INTEGER, DIMENSION(:), INTENT(  out), OPTIONAL ::   kdimsz   ! size of each dimension 
    819       INTEGER,               INTENT(  out), OPTIONAL ::   kndims   ! size of the dimensions 
     830      INTEGER              , INTENT(  out), OPTIONAL ::   kndims   ! number of dimensions 
     831      LOGICAL              , INTENT(  out), OPTIONAL ::   lduld    ! true if the last dimension is unlimited (time) 
    820832      LOGICAL              , INTENT(in   ), OPTIONAL ::   ldstop   ! stop if looking for non-existing variable (default = .TRUE.) 
    821833      ! 
     
    847859               iiv = iiv + 1 
    848860               IF( iiv <= jpmax_vars ) THEN 
    849                   iom_varid = iom_nf90_varid( kiomid, cdvar, iiv, kdimsz, kndims ) 
     861                  iom_varid = iom_nf90_varid( kiomid, cdvar, iiv, kdimsz, kndims, lduld ) 
    850862               ELSE 
    851863                  CALL ctl_stop( trim(clinfo), 'Too many variables in the file '//iom_file(kiomid)%name,   & 
     
    865877               ENDIF 
    866878               IF( PRESENT(kndims) )  kndims = iom_file(kiomid)%ndims(iiv) 
     879               IF( PRESENT( lduld) )  lduld  = iom_file(kiomid)%luld( iiv) 
    867880            ENDIF 
    868881         ENDIF 
     
    875888   !!                   INTERFACE iom_get 
    876889   !!---------------------------------------------------------------------- 
    877    SUBROUTINE iom_g0d( kiomid, cdvar, pvar, ktime, ldxios ) 
     890   SUBROUTINE iom_g0d_sp( kiomid, cdvar, pvar, ktime, ldxios ) 
    878891      INTEGER         , INTENT(in   )                 ::   kiomid    ! Identifier of the file 
    879892      CHARACTER(len=*), INTENT(in   )                 ::   cdvar     ! Name of the variable 
    880       REAL(wp)        , INTENT(  out)                 ::   pvar      ! read field 
     893      REAL(sp)        , INTENT(  out)                 ::   pvar      ! read field 
     894      REAL(dp)                                        ::   ztmp_pvar ! tmp var to read field 
     895      INTEGER         , INTENT(in   ),     OPTIONAL   ::   ktime     ! record number 
     896      LOGICAL         , INTENT(in   ),     OPTIONAL   ::   ldxios    ! use xios to read restart 
     897      ! 
     898      INTEGER                                         ::   idvar     ! variable id 
     899      INTEGER                                         ::   idmspc    ! number of spatial dimensions 
     900      INTEGER         , DIMENSION(1)                  ::   itime     ! record number 
     901      CHARACTER(LEN=100)                              ::   clinfo    ! info character 
     902      CHARACTER(LEN=100)                              ::   clname    ! file name 
     903      CHARACTER(LEN=1)                                ::   cldmspc   ! 
     904      LOGICAL                                         ::   llxios 
     905      ! 
     906      llxios = .FALSE. 
     907      IF( PRESENT(ldxios) ) llxios = ldxios 
     908 
     909      IF(.NOT.llxios) THEN  ! read data using default library 
     910         itime = 1 
     911         IF( PRESENT(ktime) ) itime = ktime 
     912         ! 
     913         clname = iom_file(kiomid)%name 
     914         clinfo = '          iom_g0d, file: '//trim(clname)//', var: '//trim(cdvar) 
     915         ! 
     916         IF( kiomid > 0 ) THEN 
     917            idvar = iom_varid( kiomid, cdvar ) 
     918            IF( iom_file(kiomid)%nfid > 0 .AND. idvar > 0 ) THEN 
     919               idmspc = iom_file ( kiomid )%ndims( idvar ) 
     920               IF( iom_file(kiomid)%luld(idvar) )  idmspc = idmspc - 1 
     921               WRITE(cldmspc , fmt='(i1)') idmspc 
     922               IF( idmspc > 0 )  CALL ctl_stop( TRIM(clinfo), 'When reading to a 0D array, we do not accept data', & 
     923                                    &                         'with 1 or more spatial dimensions: '//cldmspc//' were found.' , & 
     924                                    &                         'Use ncwa -a to suppress the unnecessary dimensions' ) 
     925               CALL iom_nf90_get( kiomid, idvar, ztmp_pvar, itime ) 
     926               pvar = ztmp_pvar 
     927            ENDIF 
     928         ENDIF 
     929      ELSE 
     930#if defined key_iomput 
     931         IF(lwp) WRITE(numout,*) 'XIOS RST READ (0D): ', trim(cdvar) 
     932         CALL iom_swap( TRIM(crxios_context) ) 
     933         CALL xios_recv_field( trim(cdvar), pvar) 
     934         CALL iom_swap( TRIM(cxios_context) ) 
     935#else 
     936         WRITE(ctmp1,*) 'Can not use XIOS in iom_g0d, file: '//trim(clname)//', var:'//trim(cdvar) 
     937         CALL ctl_stop( 'iom_g0d', ctmp1 ) 
     938#endif 
     939      ENDIF 
     940   END SUBROUTINE iom_g0d_sp 
     941 
     942   SUBROUTINE iom_g0d_dp( kiomid, cdvar, pvar, ktime, ldxios ) 
     943      INTEGER         , INTENT(in   )                 ::   kiomid    ! Identifier of the file 
     944      CHARACTER(len=*), INTENT(in   )                 ::   cdvar     ! Name of the variable 
     945      REAL(dp)        , INTENT(  out)                 ::   pvar      ! read field 
    881946      INTEGER         , INTENT(in   ),     OPTIONAL   ::   ktime     ! record number 
    882947      LOGICAL         , INTENT(in   ),     OPTIONAL   ::   ldxios    ! use xios to read restart 
     
    913978         ENDIF 
    914979      ELSE 
    915 #if defined key_xios 
     980#if defined key_iomput 
    916981         IF(lwp) WRITE(numout,*) 'XIOS RST READ (0D): ', trim(cdvar) 
    917982         CALL iom_swap( TRIM(crxios_context) ) 
     
    923988#endif 
    924989      ENDIF 
    925    END SUBROUTINE iom_g0d 
    926  
    927    SUBROUTINE iom_g1d( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, ldxios ) 
     990   END SUBROUTINE iom_g0d_dp 
     991 
     992   SUBROUTINE iom_g1d_sp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, ldxios ) 
    928993      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file 
    929994      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read 
    930995      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable 
    931       REAL(wp)        , INTENT(  out), DIMENSION(:)           ::   pvar      ! read field 
     996      REAL(sp)        , INTENT(  out), DIMENSION(:)           ::   pvar      ! read field 
     997      REAL(dp)        , ALLOCATABLE  , DIMENSION(:)           ::   ztmp_pvar ! tmp var to read field 
    932998      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number 
    933999      INTEGER         , INTENT(in   ), DIMENSION(1), OPTIONAL ::   kstart    ! start axis position of the reading  
     
    9361002      ! 
    9371003      IF( kiomid > 0 ) THEN 
     1004         IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1005            ALLOCATE(ztmp_pvar(size(pvar,1))) 
     1006            CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r1d=ztmp_pvar,   & 
     1007              &                                                     ktime=ktime, kstart=kstart, kcount=kcount, & 
     1008              &                                                     ldxios=ldxios ) 
     1009            pvar = ztmp_pvar 
     1010            DEALLOCATE(ztmp_pvar) 
     1011         END IF 
     1012      ENDIF 
     1013   END SUBROUTINE iom_g1d_sp 
     1014 
     1015 
     1016   SUBROUTINE iom_g1d_dp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, ldxios ) 
     1017      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file 
     1018      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read 
     1019      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable 
     1020      REAL(dp)        , INTENT(  out), DIMENSION(:)           ::   pvar      ! read field 
     1021      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number 
     1022      INTEGER         , INTENT(in   ), DIMENSION(1), OPTIONAL ::   kstart    ! start axis position of the reading  
     1023      INTEGER         , INTENT(in   ), DIMENSION(1), OPTIONAL ::   kcount    ! number of points in each axis 
     1024      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios    ! read data using XIOS 
     1025      ! 
     1026      IF( kiomid > 0 ) THEN 
    9381027         IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r1d=pvar,   & 
    9391028              &                                                     ktime=ktime, kstart=kstart, kcount=kcount, & 
    9401029              &                                                     ldxios=ldxios ) 
    9411030      ENDIF 
    942    END SUBROUTINE iom_g1d 
    943  
    944    SUBROUTINE iom_g2d( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios) 
    945       INTEGER         , INTENT(in   )                           ::   kiomid    ! Identifier of the file 
    946       INTEGER         , INTENT(in   )                           ::   kdom      ! Type of domain to be read 
    947       CHARACTER(len=*), INTENT(in   )                           ::   cdvar     ! Name of the variable 
    948       REAL(wp)        , INTENT(  out), DIMENSION(:,:)           ::   pvar      ! read field 
    949       INTEGER         , INTENT(in   )                , OPTIONAL ::   ktime     ! record number 
    950       INTEGER         , INTENT(in   ), DIMENSION(2)  , OPTIONAL ::   kstart    ! start axis position of the reading  
    951       INTEGER         , INTENT(in   ), DIMENSION(2)  , OPTIONAL ::   kcount    ! number of points in each axis 
    952       LOGICAL         , INTENT(in   )                , OPTIONAL ::   lrowattr  ! logical flag telling iom_get to 
    953                                                                                ! look for and use a file attribute 
    954                                                                                ! called open_ocean_jstart to set the start 
    955                                                                                ! value for the 2nd dimension (netcdf only) 
    956       LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios      ! read data using XIOS 
     1031   END SUBROUTINE iom_g1d_dp 
     1032 
     1033   SUBROUTINE iom_g2d_sp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, kstart, kcount, ldxios) 
     1034      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file 
     1035      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read 
     1036      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable 
     1037      REAL(sp)        , INTENT(  out), DIMENSION(:,:)         ::   pvar      ! read field 
     1038      REAL(dp)        , ALLOCATABLE  , DIMENSION(:,:)         ::   ztmp_pvar ! tmp var to read field 
     1039      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number 
     1040      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W) 
     1041      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.): (not) change sign across the north fold 
     1042      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk 
     1043      INTEGER         , INTENT(in   ), DIMENSION(2), OPTIONAL ::   kstart    ! start axis position of the reading  
     1044      INTEGER         , INTENT(in   ), DIMENSION(2), OPTIONAL ::   kcount    ! number of points in each axis 
     1045      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios    ! read data using XIOS 
    9571046      ! 
    9581047      IF( kiomid > 0 ) THEN 
    959          IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r2d=pvar,   & 
    960               &                                                     ktime=ktime, kstart=kstart, kcount=kcount, & 
    961               &                                                     lrowattr=lrowattr,  ldxios=ldxios) 
    962       ENDIF 
    963    END SUBROUTINE iom_g2d 
    964  
    965    SUBROUTINE iom_g3d( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios ) 
    966       INTEGER         , INTENT(in   )                             ::   kiomid    ! Identifier of the file 
    967       INTEGER         , INTENT(in   )                             ::   kdom      ! Type of domain to be read 
    968       CHARACTER(len=*), INTENT(in   )                             ::   cdvar     ! Name of the variable 
    969       REAL(wp)        , INTENT(  out), DIMENSION(:,:,:)           ::   pvar      ! read field 
    970       INTEGER         , INTENT(in   )                  , OPTIONAL ::   ktime     ! record number 
    971       INTEGER         , INTENT(in   ), DIMENSION(3)    , OPTIONAL ::   kstart    ! start axis position of the reading  
    972       INTEGER         , INTENT(in   ), DIMENSION(3)    , OPTIONAL ::   kcount    ! number of points in each axis 
    973       LOGICAL         , INTENT(in   )                  , OPTIONAL ::   lrowattr  ! logical flag telling iom_get to 
    974                                                                                  ! look for and use a file attribute 
    975                                                                                  ! called open_ocean_jstart to set the start 
    976                                                                                  ! value for the 2nd dimension (netcdf only) 
    977       LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios        ! read data using XIOS 
     1048         IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1049            ALLOCATE(ztmp_pvar(size(pvar,1), size(pvar,2))) 
     1050            CALL iom_get_123d( kiomid, kdom, cdvar      , pv_r2d = ztmp_pvar  , ktime = ktime,   & 
     1051             &                                                      cd_type = cd_type, psgn   = psgn  , kfill = kfill,   & 
     1052             &                                                      kstart  = kstart , kcount = kcount, ldxios=ldxios  ) 
     1053            pvar = ztmp_pvar 
     1054            DEALLOCATE(ztmp_pvar) 
     1055         ENDIF 
     1056      ENDIF 
     1057   END SUBROUTINE iom_g2d_sp 
     1058 
     1059   SUBROUTINE iom_g2d_dp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, kstart, kcount, ldxios) 
     1060      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file 
     1061      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read 
     1062      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable 
     1063      REAL(dp)        , INTENT(  out), DIMENSION(:,:)         ::   pvar      ! read field 
     1064      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number 
     1065      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W) 
     1066      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.): (not) change sign across the north fold 
     1067      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk 
     1068      INTEGER         , INTENT(in   ), DIMENSION(2), OPTIONAL ::   kstart    ! start axis position of the reading  
     1069      INTEGER         , INTENT(in   ), DIMENSION(2), OPTIONAL ::   kcount    ! number of points in each axis 
     1070      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios    ! read data using XIOS 
    9781071      ! 
    9791072      IF( kiomid > 0 ) THEN 
    980          IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r3d=pvar,   & 
    981               &                                                     ktime=ktime, kstart=kstart, kcount=kcount, & 
    982               &                                                     lrowattr=lrowattr, ldxios=ldxios ) 
    983       ENDIF 
    984    END SUBROUTINE iom_g3d 
     1073         IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom, cdvar      , pv_r2d = pvar  , ktime = ktime,   & 
     1074            &                                                       cd_type = cd_type, psgn   = psgn  , kfill = kfill,   & 
     1075            &                                                       kstart  = kstart , kcount = kcount, ldxios=ldxios  ) 
     1076      ENDIF 
     1077   END SUBROUTINE iom_g2d_dp 
     1078 
     1079   SUBROUTINE iom_g3d_sp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, kstart, kcount, ldxios ) 
     1080      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file 
     1081      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read 
     1082      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable 
     1083      REAL(sp)        , INTENT(  out), DIMENSION(:,:,:)       ::   pvar      ! read field 
     1084      REAL(dp)        , ALLOCATABLE  , DIMENSION(:,:,:)       ::   ztmp_pvar ! tmp var to read field 
     1085      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number 
     1086      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W) 
     1087      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.) : (not) change sign across the north fold 
     1088      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk 
     1089      INTEGER         , INTENT(in   ), DIMENSION(3), OPTIONAL ::   kstart    ! start axis position of the reading  
     1090      INTEGER         , INTENT(in   ), DIMENSION(3), OPTIONAL ::   kcount    ! number of points in each axis 
     1091      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios    ! read data using XIOS 
     1092      ! 
     1093      IF( kiomid > 0 ) THEN 
     1094         IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1095            ALLOCATE(ztmp_pvar(size(pvar,1), size(pvar,2), size(pvar,3))) 
     1096            CALL iom_get_123d( kiomid, kdom, cdvar      , pv_r3d = ztmp_pvar  , ktime = ktime,   & 
     1097            &                                                       cd_type = cd_type, psgn   = psgn  , kfill = kfill,   & 
     1098            &                                                       kstart  = kstart , kcount = kcount, ldxios=ldxios  ) 
     1099            pvar = ztmp_pvar 
     1100            DEALLOCATE(ztmp_pvar) 
     1101         END IF 
     1102      ENDIF 
     1103   END SUBROUTINE iom_g3d_sp 
     1104 
     1105   SUBROUTINE iom_g3d_dp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, kstart, kcount, ldxios ) 
     1106      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file 
     1107      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read 
     1108      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable 
     1109      REAL(dp)        , INTENT(  out), DIMENSION(:,:,:)       ::   pvar      ! read field 
     1110      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number 
     1111      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W) 
     1112      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.) : (not) change sign across the north fold 
     1113      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk 
     1114      INTEGER         , INTENT(in   ), DIMENSION(3), OPTIONAL ::   kstart    ! start axis position of the reading  
     1115      INTEGER         , INTENT(in   ), DIMENSION(3), OPTIONAL ::   kcount    ! number of points in each axis 
     1116      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios    ! read data using XIOS 
     1117      ! 
     1118      IF( kiomid > 0 ) THEN 
     1119         IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1120            CALL iom_get_123d( kiomid, kdom, cdvar      , pv_r3d = pvar  , ktime = ktime,   & 
     1121            &                                                       cd_type = cd_type, psgn   = psgn  , kfill = kfill,   & 
     1122            &                                                       kstart  = kstart , kcount = kcount, ldxios=ldxios  ) 
     1123         END IF 
     1124      ENDIF 
     1125   END SUBROUTINE iom_g3d_dp 
     1126 
    9851127   !!---------------------------------------------------------------------- 
    9861128 
    987    SUBROUTINE iom_get_123d( kiomid, kdom  , cdvar ,   & 
    988          &                  pv_r1d, pv_r2d, pv_r3d,   & 
    989          &                  ktime , kstart, kcount,   & 
    990          &                  lrowattr, ldxios        ) 
     1129   SUBROUTINE iom_get_123d( kiomid , kdom, cdvar, pv_r1d, pv_r2d, pv_r3d, ktime ,   & 
     1130         &                  cd_type, psgn, kfill, kstart, kcount, ldxios ) 
    9911131      !!----------------------------------------------------------------------- 
    9921132      !!                  ***  ROUTINE  iom_get_123d  *** 
     
    9961136      !! ** Method : read ONE record at each CALL 
    9971137      !!----------------------------------------------------------------------- 
    998       INTEGER                    , INTENT(in   )           ::   kiomid     ! Identifier of the file 
    999       INTEGER                    , INTENT(in   )           ::   kdom       ! Type of domain to be read 
    1000       CHARACTER(len=*)           , INTENT(in   )           ::   cdvar      ! Name of the variable 
    1001       REAL(wp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d     ! read field (1D case) 
    1002       REAL(wp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d     ! read field (2D case) 
    1003       REAL(wp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d     ! read field (3D case) 
    1004       INTEGER                    , INTENT(in   ), OPTIONAL ::   ktime      ! record number 
    1005       INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kstart     ! start position of the reading in each axis  
    1006       INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kcount     ! number of points to be read in each axis 
    1007       LOGICAL                    , INTENT(in   ), OPTIONAL ::   lrowattr   ! logical flag telling iom_get to 
    1008                                                                            ! look for and use a file attribute 
    1009                                                                            ! called open_ocean_jstart to set the start 
    1010                                                                            ! value for the 2nd dimension (netcdf only) 
    1011       LOGICAL                    , INTENT(in   ), OPTIONAL ::   ldxios     ! use XIOS to read restart 
    1012       ! 
    1013       LOGICAL                        ::   llxios       ! local definition for XIOS read 
    1014       LOGICAL                        ::   llnoov      ! local definition to read overlap 
    1015       LOGICAL                        ::   luse_jattr  ! local definition to read open_ocean_jstart file attribute 
    1016       INTEGER                        ::   jstartrow   ! start point for 2nd dimension optionally set by file attribute 
     1138      INTEGER                    , INTENT(in   )           ::   kiomid    ! Identifier of the file 
     1139      INTEGER                    , INTENT(in   )           ::   kdom      ! Type of domain to be read 
     1140      CHARACTER(len=*)           , INTENT(in   )           ::   cdvar     ! Name of the variable 
     1141      REAL(dp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d    ! read field (1D case) 
     1142      REAL(dp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d    ! read field (2D case) 
     1143      REAL(dp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d    ! read field (3D case) 
     1144      INTEGER                    , INTENT(in   ), OPTIONAL ::   ktime     ! record number 
     1145      CHARACTER(len=1)           , INTENT(in   ), OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W) 
     1146      REAL(dp)                   , INTENT(in   ), OPTIONAL ::   psgn      ! -1.(1.) : (not) change sign across the north fold 
     1147      INTEGER                    , INTENT(in   ), OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk 
     1148      INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kstart    ! start position of the reading in each axis  
     1149      INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kcount    ! number of points to be read in each axis 
     1150      LOGICAL                    , INTENT(in   ), OPTIONAL ::   ldxios    ! use XIOS to read restart 
     1151      ! 
     1152      LOGICAL                        ::   llok        ! true if ok! 
     1153      LOGICAL                        ::   llxios      ! local definition for XIOS read 
    10171154      INTEGER                        ::   jl          ! loop on number of dimension  
    10181155      INTEGER                        ::   idom        ! type of domain 
     
    10301167      INTEGER, DIMENSION(jpmax_dims) ::   idimsz      ! size of the dimensions of the variable 
    10311168      INTEGER, DIMENSION(jpmax_dims) ::   ishape      ! size of the dimensions of the variable 
    1032       REAL(wp)                       ::   zscf, zofs  ! sacle_factor and add_offset 
     1169      REAL(dp)                       ::   zscf, zofs  ! sacle_factor and add_offset 
     1170      REAL(wp)                       ::   zsgn        ! local value of psgn 
    10331171      INTEGER                        ::   itmp        ! temporary integer 
    10341172      CHARACTER(LEN=256)             ::   clinfo      ! info character 
    10351173      CHARACTER(LEN=256)             ::   clname      ! file name 
    10361174      CHARACTER(LEN=1)               ::   clrankpv, cldmspc      !  
    1037       LOGICAL                        ::   ll_depth_spec ! T => if kstart, kcount present then *only* use values for 3rd spatial dimension. 
     1175      CHARACTER(LEN=1)               ::   cl_type     ! local value of cd_type 
     1176      LOGICAL                        ::   ll_only3rd  ! T => if kstart, kcount present then *only* use values for 3rd spatial dimension. 
    10381177      INTEGER                        ::   inlev       ! number of levels for 3D data 
    1039       REAL(wp)                       ::   gma, gmi 
     1178      REAL(dp)                       ::   gma, gmi 
    10401179      !--------------------------------------------------------------------- 
    10411180      ! 
     
    10441183      ! 
    10451184      llxios = .FALSE. 
    1046       if(PRESENT(ldxios)) llxios = ldxios 
    1047       idvar = iom_varid( kiomid, cdvar )  
     1185      IF( PRESENT(ldxios) )  llxios = ldxios 
     1186      ! 
    10481187      idom = kdom 
     1188      istop = nstop 
    10491189      ! 
    10501190      IF(.NOT.llxios) THEN 
    10511191         clname = iom_file(kiomid)%name   !   esier to read 
    10521192         clinfo = '          iom_get_123d, file: '//trim(clname)//', var: '//trim(cdvar) 
    1053          ! local definition of the domain ? 
    1054          ! do we read the overlap  
    1055          ! ugly patch SM+JMM+RB to overwrite global definition in some cases 
    1056          !  
    1057          !llnoov = (jpni * jpnj ) == jpnij .AND. .NOT. lk_agrif  
    1058          ! for domain_cfg tools force to read the full domain 
    1059          llnoov = .FALSE. 
    10601193         ! check kcount and kstart optionals parameters... 
    1061          IF( PRESENT(kcount) .AND. (.NOT. PRESENT(kstart)) ) CALL ctl_stop(trim(clinfo), 'kcount present needs kstart present') 
    1062          IF( PRESENT(kstart) .AND. (.NOT. PRESENT(kcount)) ) CALL ctl_stop(trim(clinfo), 'kstart present needs kcount present') 
    1063          IF( PRESENT(kstart) .AND. idom /= jpdom_unknown .AND.  idom /= jpdom_autoglo_xy  ) & 
    1064      &          CALL ctl_stop(trim(clinfo), 'kstart present needs kdom = jpdom_unknown or kdom = jpdom_autoglo_xy') 
    1065  
    1066          luse_jattr = .false. 
    1067          IF( PRESENT(lrowattr) ) THEN 
    1068             IF( lrowattr .AND. idom /= jpdom_data   ) CALL ctl_stop(trim(clinfo), 'lrowattr present and true needs kdom = jpdom_data') 
    1069             IF( lrowattr .AND. idom == jpdom_data   ) luse_jattr = .true. 
    1070          ENDIF 
    1071  
     1194         IF( PRESENT(kcount) .AND. .NOT. PRESENT(kstart) ) CALL ctl_stop(trim(clinfo), 'kcount present needs kstart present') 
     1195         IF( PRESENT(kstart) .AND. .NOT. PRESENT(kcount) ) CALL ctl_stop(trim(clinfo), 'kstart present needs kcount present') 
     1196         IF( PRESENT(kstart) .AND. idom /= jpdom_unknown .AND. idom /= jpdom_auto_xy ) & 
     1197            &          CALL ctl_stop(TRIM(clinfo), 'kstart present needs idom = jpdom_unknown or idom = jpdom_auto_xy') 
     1198         IF( idom == jpdom_auto_xy .AND. .NOT. PRESENT(kstart) ) & 
     1199            &          CALL ctl_stop(TRIM(clinfo), 'idom = jpdom_auto_xy requires kstart to be present') 
     1200         ! 
    10721201         ! Search for the variable in the data base (eventually actualize data) 
    1073          istop = nstop 
    10741202         ! 
     1203         idvar = iom_varid( kiomid, cdvar )  
    10751204         IF( idvar > 0 ) THEN 
    1076             ! to write iom_file(kiomid)%dimsz in a shorter way ! 
    1077             idimsz(:) = iom_file(kiomid)%dimsz(:, idvar)  
     1205            ! 
     1206            idimsz(:) = iom_file(kiomid)%dimsz(:, idvar)      ! to write iom_file(kiomid)%dimsz in a shorter way 
    10781207            inbdim = iom_file(kiomid)%ndims(idvar)            ! number of dimensions in the file 
    10791208            idmspc = inbdim                                   ! number of spatial dimensions in the file 
     
    10811210            IF( idmspc > 3 )   CALL ctl_stop(trim(clinfo), 'the file has more than 3 spatial dimensions this case is not coded...')  
    10821211            ! 
    1083             ! update idom definition... 
    1084             ! Identify the domain in case of jpdom_auto(glo/dta) definition 
    1085             IF( idom == jpdom_autoglo_xy ) THEN 
    1086                ll_depth_spec = .TRUE. 
    1087                idom = jpdom_autoglo 
    1088             ELSE 
    1089                ll_depth_spec = .FALSE. 
    1090             ENDIF 
    1091             IF( idom == jpdom_autoglo .OR. idom == jpdom_autodta ) THEN             
    1092                IF( idom == jpdom_autoglo ) THEN   ;   idom = jpdom_global  
    1093                ELSE                               ;   idom = jpdom_data 
    1094                ENDIF 
     1212            ! Identify the domain in case of jpdom_auto definition 
     1213            IF( idom == jpdom_auto .OR. idom == jpdom_auto_xy ) THEN             
     1214               idom = jpdom_global   ! default 
     1215               ! else: if the file name finishes with _xxxx.nc with xxxx any number 
    10951216               ind1 = INDEX( clname, '_', back = .TRUE. ) + 1 
    10961217               ind2 = INDEX( clname, '.', back = .TRUE. ) - 1 
    10971218               IF( ind2 > ind1 ) THEN   ;   IF( VERIFY( clname(ind1:ind2), '0123456789' ) == 0 )   idom = jpdom_local   ;   ENDIF 
    1098             ENDIF 
    1099             ! Identify the domain in case of jpdom_local definition 
    1100             IF( idom == jpdom_local ) THEN 
    1101                IF(     idimsz(1) == jpi               .AND. idimsz(2) == jpj               ) THEN   ;   idom = jpdom_local_full 
    1102                ELSEIF( idimsz(1) == nlci              .AND. idimsz(2) == nlcj              ) THEN   ;   idom = jpdom_local_noextra 
    1103                ELSEIF( idimsz(1) == (nlei - nldi + 1) .AND. idimsz(2) == (nlej - nldj + 1) ) THEN   ;   idom = jpdom_local_noovlap 
    1104                ELSE   ;   CALL ctl_stop( trim(clinfo), 'impossible to identify the local domain' ) 
    1105                ENDIF 
    11061219            ENDIF 
    11071220            ! 
     
    11161229            WRITE(cldmspc , fmt='(i1)') idmspc 
    11171230            ! 
    1118             IF(     idmspc <  irankpv ) THEN  
    1119                CALL ctl_stop( TRIM(clinfo), 'The file has only '//cldmspc//' spatial dimension',   & 
    1120                   &                         'it is impossible to read a '//clrankpv//'D array from this file...' ) 
     1231            IF(     idmspc <  irankpv ) THEN                     ! it seems we want to read more than we can... 
     1232               IF(     irankpv == 3 .AND. idmspc == 2 ) THEN     !   3D input array from 2D spatial data in the file: 
     1233                  llok = inlev == 1                              !     -> 3rd dimension must be equal to 1 
     1234               ELSEIF( irankpv == 3 .AND. idmspc == 1 ) THEN     !   3D input array from 1D spatial data in the file: 
     1235                  llok = inlev == 1 .AND. SIZE(pv_r3d, 2) == 1   !     -> 2nd and 3rd dimensions must be equal to 1 
     1236               ELSEIF( irankpv == 2 .AND. idmspc == 2 ) THEN     !   2D input array from 1D spatial data in the file: 
     1237                  llok = SIZE(pv_r2d, 2) == 1                    !     -> 2nd dimension must be equal to 1 
     1238               ELSE 
     1239                  llok = .FALSE. 
     1240               ENDIF 
     1241               IF( .NOT. llok )   CALL ctl_stop( TRIM(clinfo), 'The file has only '//cldmspc//' spatial dimension',   & 
     1242                  &                                            '=> cannot read a true '//clrankpv//'D array from this file...' ) 
    11211243            ELSEIF( idmspc == irankpv ) THEN 
    11221244               IF( PRESENT(pv_r1d) .AND. idom /= jpdom_unknown )   & 
    11231245                  &   CALL ctl_stop( TRIM(clinfo), 'case not coded...You must use jpdom_unknown' ) 
    1124             ELSEIF( idmspc >  irankpv ) THEN 
     1246            ELSEIF( idmspc >  irankpv ) THEN                     ! it seems we want to read less than we should... 
    11251247                  IF( PRESENT(pv_r2d) .AND. itime == 1 .AND. idimsz(3) == 1 .AND. idmspc == 3 ) THEN 
    1126                      CALL ctl_warn( trim(clinfo), '2D array but 3 spatial dimensions for the data...'              ,   & 
     1248                     CALL ctl_warn( trim(clinfo), '2D array input but 3 spatial dimensions in the file...'              ,   & 
    11271249                           &         'As the size of the z dimension is 1 and as we try to read the first record, ',   & 
    11281250                           &         'we accept this case, even if there is a possible mix-up between z and time dimension' )    
    11291251                     idmspc = idmspc - 1 
    1130                   ELSE 
    1131                      CALL ctl_stop( TRIM(clinfo), 'To keep iom lisibility, when reading a '//clrankpv//'D array,'         ,   & 
    1132                         &                         'we do not accept data with '//cldmspc//' spatial dimensions',   & 
    1133                         &                         'Use ncwa -a to suppress the unnecessary dimensions' ) 
     1252                  !!GS: possibility to read 3D ABL atmopsheric forcing and use 1st level to force BULK simulation 
     1253                  !ELSE 
     1254                  !   CALL ctl_stop( TRIM(clinfo), 'To keep iom lisibility, when reading a '//clrankpv//'D array,',   & 
     1255                  !      &                         'we do not accept data with '//cldmspc//' spatial dimensions'  ,   & 
     1256                  !      &                         'Use ncwa -a to suppress the unnecessary dimensions' ) 
    11341257                  ENDIF 
    11351258            ENDIF 
     
    11371260            ! definition of istart and icnt 
    11381261            ! 
    1139             icnt  (:) = 1 
    1140             istart(:) = 1 
    1141             istart(idmspc+1) = itime 
    1142     
    1143             IF( PRESENT(kstart) .AND. .NOT. ll_depth_spec ) THEN  
    1144                istart(1:idmspc) = kstart(1:idmspc)  
    1145                icnt  (1:idmspc) = kcount(1:idmspc) 
    1146             ELSE 
    1147                IF(idom == jpdom_unknown ) THEN 
    1148                   icnt(1:idmspc) = idimsz(1:idmspc) 
    1149                ELSE  
    1150                   IF( .NOT. PRESENT(pv_r1d) ) THEN   !   not a 1D array 
    1151                      IF(     idom == jpdom_data    ) THEN 
    1152                         jstartrow = 1 
    1153                         IF( luse_jattr ) THEN 
    1154                            CALL iom_getatt(kiomid, 'open_ocean_jstart', jstartrow ) ! -999 is returned if the attribute is not found 
    1155                            jstartrow = MAX(1,jstartrow) 
    1156                         ENDIF 
    1157                         istart(1:2) = (/ mig(1), mjg(1) + jstartrow - 1 /)  ! icnt(1:2) done below 
    1158                      ELSEIF( idom == jpdom_global  ) THEN ; istart(1:2) = (/ nimpp , njmpp  /)  ! icnt(1:2) done below 
    1159                      ENDIF 
    1160                      ! we do not read the overlap                     -> we start to read at nldi, nldj 
    1161 ! JMM + SM: ugly patch before getting the new version of lib_mpp) 
    1162 !                  IF( idom /= jpdom_local_noovlap )   istart(1:2) = istart(1:2) + (/ nldi - 1, nldj - 1 /) 
    1163                      IF( llnoov .AND. idom /= jpdom_local_noovlap ) istart(1:2) = istart(1:2) + (/ nldi - 1, nldj - 1 /) 
    1164                   ! we do not read the overlap and the extra-halos -> from nldi to nlei and from nldj to nlej  
    1165 ! JMM + SM: ugly patch before getting the new version of lib_mpp) 
    1166 !                  icnt(1:2) = (/ nlei - nldi + 1, nlej - nldj + 1 /) 
    1167                      IF( llnoov ) THEN   ;   icnt(1:2) = (/ nlei - nldi + 1, nlej - nldj + 1 /) 
    1168                      ELSE                ;   icnt(1:2) = (/ nlci           , nlcj            /) 
    1169                      ENDIF 
    1170                      IF( PRESENT(pv_r3d) ) THEN 
    1171                         IF( idom == jpdom_data ) THEN                        ;                               icnt(3) = inlev 
    1172                         ELSEIF( ll_depth_spec .AND. PRESENT(kstart) ) THEN   ;   istart(3) = kstart(3)   ;   icnt(3) = kcount(3) 
    1173                         ELSE                                                 ;                               icnt(3) = inlev 
    1174                         ENDIF 
    1175                      ENDIF 
     1262            icnt  (:) = 1              ! default definition (simple way to deal with special cases listed above)  
     1263            istart(:) = 1              ! default definition (simple way to deal with special cases listed above)  
     1264            istart(idmspc+1) = itime   ! temporal dimenstion 
     1265            ! 
     1266            IF( idom == jpdom_unknown ) THEN 
     1267               IF( PRESENT(kstart) .AND. idom /= jpdom_auto_xy ) THEN  
     1268                  istart(1:idmspc) = kstart(1:idmspc)  
     1269                  icnt  (1:idmspc) = kcount(1:idmspc) 
     1270               ELSE 
     1271                  icnt  (1:idmspc) = idimsz(1:idmspc) 
     1272               ENDIF 
     1273            ELSE   !   not a 1D array as pv_r1d requires jpdom_unknown 
     1274               ! we do not read the overlap and the extra-halos -> from Nis0 to Nie0 and from Njs0 to Nje0  
     1275               IF( idom == jpdom_global )   istart(1:2) = (/ mig0(Nis0), mjg0(Njs0) /) 
     1276               icnt(1:2) = (/ Ni_0, Nj_0 /) 
     1277               IF( PRESENT(pv_r3d) ) THEN 
     1278                  IF( idom == jpdom_auto_xy ) THEN 
     1279                     istart(3) = kstart(3) 
     1280                     icnt  (3) = kcount(3) 
     1281                  ELSE 
     1282                     icnt  (3) = inlev 
    11761283                  ENDIF 
    11771284               ENDIF 
    11781285            ENDIF 
    1179  
     1286            ! 
    11801287            ! check that istart and icnt can be used with this file 
    11811288            !- 
     
    11881295               ENDIF 
    11891296            END DO 
    1190  
     1297            ! 
    11911298            ! check that icnt matches the input array 
    11921299            !-      
     
    11981305            ELSE 
    11991306               IF( irankpv == 2 ) THEN 
    1200 ! JMM + SM: ugly patch before getting the new version of lib_mpp) 
    1201 !               ishape(1:2) = SHAPE(pv_r2d(nldi:nlei,nldj:nlej  ))   ;   ctmp1 = 'd(nldi:nlei,nldj:nlej)' 
    1202                   IF( llnoov ) THEN ; ishape(1:2)=SHAPE(pv_r2d(nldi:nlei,nldj:nlej  )) ; ctmp1='d(nldi:nlei,nldj:nlej)' 
    1203                   ELSE              ; ishape(1:2)=SHAPE(pv_r2d(1   :nlci,1   :nlcj  )) ; ctmp1='d(1:nlci,1:nlcj)' 
    1204                   ENDIF 
     1307                  ishape(1:2) = SHAPE(pv_r2d(Nis0:Nie0,Njs0:Nje0  ))   ;   ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0)' 
    12051308               ENDIF 
    12061309               IF( irankpv == 3 ) THEN  
    1207 ! JMM + SM: ugly patch before getting the new version of lib_mpp) 
    1208 !               ishape(1:3) = SHAPE(pv_r3d(nldi:nlei,nldj:nlej,:))   ;   ctmp1 = 'd(nldi:nlei,nldj:nlej,:)' 
    1209                   IF( llnoov ) THEN ; ishape(1:3)=SHAPE(pv_r3d(nldi:nlei,nldj:nlej,:)) ; ctmp1='d(nldi:nlei,nldj:nlej,:)' 
    1210                   ELSE              ; ishape(1:3)=SHAPE(pv_r3d(1   :nlci,1   :nlcj,:)) ; ctmp1='d(1:nlci,1:nlcj,:)' 
    1211                   ENDIF 
     1310                  ishape(1:3) = SHAPE(pv_r3d(Nis0:Nie0,Njs0:Nje0,:))   ;   ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0,:)' 
    12121311               ENDIF 
    1213             ENDIF 
    1214           
     1312            ENDIF          
    12151313            DO jl = 1, irankpv 
    12161314               WRITE( ctmp2, FMT="(', ', i1,'): ', i5,' /= icnt(', i1,'):', i5)" ) jl, ishape(jl), jl, icnt(jl) 
     
    12241322         IF( idvar > 0 .AND. istop == nstop ) THEN   ! no additional errors until this point... 
    12251323            ! 
    1226          ! find the right index of the array to be read 
    1227 ! JMM + SM: ugly patch before getting the new version of lib_mpp) 
    1228 !         IF( idom /= jpdom_unknown ) THEN   ;   ix1 = nldi   ;   ix2 = nlei      ;   iy1 = nldj   ;   iy2 = nlej 
    1229 !         ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2) 
    1230 !         ENDIF 
    1231             IF( llnoov ) THEN 
    1232                IF( idom /= jpdom_unknown ) THEN   ;   ix1 = nldi   ;   ix2 = nlei      ;   iy1 = nldj   ;   iy2 = nlej 
    1233                ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2) 
    1234                ENDIF 
    1235             ELSE 
    1236                IF( idom /= jpdom_unknown ) THEN   ;   ix1 = 1      ;   ix2 = nlci      ;   iy1 = 1      ;   iy2 = nlcj 
    1237                ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2) 
    1238                ENDIF 
     1324            ! find the right index of the array to be read 
     1325            IF( idom /= jpdom_unknown ) THEN   ;   ix1 = Nis0   ;   ix2 = Nie0      ;   iy1 = Njs0   ;   iy2 = Nje0 
     1326            ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2) 
    12391327            ENDIF 
    1240  
     1328       
    12411329            CALL iom_nf90_get( kiomid, idvar, inbdim, istart, icnt, ix1, ix2, iy1, iy2, pv_r1d, pv_r2d, pv_r3d ) 
    12421330 
    12431331            IF( istop == nstop ) THEN   ! no additional errors until this point... 
    12441332               IF(lwp) WRITE(numout,"(10x,' read ',a,' (rec: ',i6,') in ',a,' ok')") TRIM(cdvar), itime, TRIM(iom_file(kiomid)%name) 
    1245               
     1333 
     1334               cl_type = 'T' 
     1335               IF( PRESENT(cd_type) )   cl_type = cd_type 
     1336               zsgn = 1._wp 
     1337               IF( PRESENT(psgn   ) )   zsgn    = psgn 
    12461338               !--- overlap areas and extra hallows (mpp) 
    1247                IF(     PRESENT(pv_r2d) .AND. idom /= jpdom_unknown ) THEN 
    1248                   CALL lbc_lnk( 'iom', pv_r2d,'Z',-999.,'no0' ) 
    1249                ELSEIF( PRESENT(pv_r3d) .AND. idom /= jpdom_unknown ) THEN 
    1250                   ! this if could be simplified with the new lbc_lnk that works with any size of the 3rd dimension 
    1251                   IF( icnt(3) == inlev ) THEN 
    1252                      CALL lbc_lnk( 'iom', pv_r3d,'Z',-999.,'no0' ) 
    1253                   ELSE   ! put some arbitrary value (a call to lbc_lnk will be done later...) 
    1254                      DO jj = nlcj+1, jpj   ;   pv_r3d(1:nlci, jj, :) = pv_r3d(1:nlci, nlej, :)   ;   END DO 
    1255                      DO ji = nlci+1, jpi   ;   pv_r3d(ji    , : , :) = pv_r3d(nlei  , :   , :)   ;   END DO 
    1256                   ENDIF 
     1339               IF(     PRESENT(pv_r2d) .AND. idom /= jpdom_unknown .AND. cl_type /= 'Z' ) THEN 
     1340                  CALL lbc_lnk( 'iom', pv_r2d, cl_type, zsgn, kfillmode = kfill ) 
     1341               ELSEIF( PRESENT(pv_r3d) .AND. idom /= jpdom_unknown .AND. cl_type /= 'Z' ) THEN 
     1342                  CALL lbc_lnk( 'iom', pv_r3d, cl_type, zsgn, kfillmode = kfill ) 
    12571343               ENDIF 
    12581344               ! 
     
    12671353         ! 
    12681354      ELSE        ! read using XIOS. Only if KEY_IOMPUT is defined 
    1269 #if defined key_xios 
     1355#if defined key_iomput 
    12701356!would be good to be able to check which context is active and swap only if current is not restart 
    12711357         CALL iom_swap( TRIM(crxios_context) )  
    12721358         IF( PRESENT(pv_r3d) ) THEN 
    1273             pv_r3d(:, :, :) = 0. 
    1274             if(lwp) write(numout,*) 'XIOS RST READ (3D): ',trim(cdvar) 
     1359            IF(lwp) WRITE(numout,*) 'XIOS RST READ (3D): ',TRIM(cdvar) 
    12751360            CALL xios_recv_field( trim(cdvar), pv_r3d) 
    1276             IF(idom /= jpdom_unknown ) then 
    1277                 CALL lbc_lnk( 'iom', pv_r3d,'Z',-999.,'no0' ) 
    1278             ENDIF 
     1361            IF(idom /= jpdom_unknown )   CALL lbc_lnk( 'iom', pv_r3d,'Z', -999., kfillmode = jpfillnothing) 
    12791362         ELSEIF( PRESENT(pv_r2d) ) THEN 
    1280             pv_r2d(:, :) = 0. 
    1281             if(lwp) write(numout,*) 'XIOS RST READ (2D): ', trim(cdvar) 
     1363            IF(lwp) WRITE(numout,*) 'XIOS RST READ (2D): ', TRIM(cdvar) 
    12821364            CALL xios_recv_field( trim(cdvar), pv_r2d) 
    1283             IF(idom /= jpdom_unknown ) THEN 
    1284                 CALL lbc_lnk('iom', pv_r2d,'Z',-999.,'no0') 
    1285             ENDIF 
     1365            IF(idom /= jpdom_unknown )   CALL lbc_lnk('iom', pv_r2d,'Z',-999., kfillmode = jpfillnothing) 
    12861366         ELSEIF( PRESENT(pv_r1d) ) THEN 
    1287             pv_r1d(:) = 0. 
    1288             if(lwp) write(numout,*) 'XIOS RST READ (1D): ', trim(cdvar) 
     1367            IF(lwp) WRITE(numout,*) 'XIOS RST READ (1D): ', TRIM(cdvar) 
    12891368            CALL xios_recv_field( trim(cdvar), pv_r1d) 
    12901369         ENDIF 
     
    12971376!some final adjustments 
    12981377      ! C1D case : always call lbc_lnk to replicate the central value over the whole 3X3 domain 
     1378 !     IF( lk_c1d .AND. PRESENT(pv_r2d) )   CALL lbc_lnk( 'iom', pv_r2d,'Z',1.0_wp ) 
     1379 !     IF( lk_c1d .AND. PRESENT(pv_r3d) )   CALL lbc_lnk( 'iom', pv_r3d,'Z',1.0_wp ) 
    12991380 
    13001381      !--- Apply scale_factor and offset 
     
    13141395   END SUBROUTINE iom_get_123d 
    13151396 
     1397   SUBROUTINE iom_get_var( cdname, z2d) 
     1398      CHARACTER(LEN=*), INTENT(in ) ::   cdname 
     1399      REAL(wp), DIMENSION(jpi,jpj) ::   z2d  
     1400#if defined key_iomput 
     1401      IF( xios_field_is_active( cdname, at_current_timestep_arg = .TRUE. ) ) THEN 
     1402         z2d(:,:) = 0._wp 
     1403         CALL xios_recv_field( cdname, z2d) 
     1404      ENDIF 
     1405#else 
     1406      IF( .FALSE. )   WRITE(numout,*) cdname, z2d ! useless test to avoid compilation warnings 
     1407#endif 
     1408   END SUBROUTINE iom_get_var 
     1409 
    13161410 
    13171411   FUNCTION iom_getszuld ( kiomid )   
     
    14701564   !!                   INTERFACE iom_rstput 
    14711565   !!---------------------------------------------------------------------- 
    1472    SUBROUTINE iom_rp0d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1566   SUBROUTINE iom_rp0d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
    14731567      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
    14741568      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
    14751569      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
    14761570      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
    1477       REAL(wp)        , INTENT(in)                         ::   pvar     ! written field 
     1571      REAL(sp)        , INTENT(in)                         ::   pvar     ! written field 
    14781572      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
    14791573      LOGICAL, OPTIONAL :: ldxios   ! xios write flag 
     
    14841578      IF(PRESENT(ldxios)) llx = ldxios 
    14851579      IF( llx ) THEN 
    1486 #ifdef key_xios 
     1580#ifdef key_iomput 
     1581      IF( kt == kwrite ) THEN 
     1582          IF(lwp) write(numout,*) 'RESTART: write (XIOS 0D) ',trim(cdvar) 
     1583          CALL xios_send_field(trim(cdvar), pvar) 
     1584      ENDIF 
     1585#endif 
     1586      ELSE 
     1587         IF( kiomid > 0 ) THEN 
     1588            IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1589               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. ) 
     1590               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r0d = real(pvar, dp) ) 
     1591            ENDIF 
     1592         ENDIF 
     1593      ENDIF 
     1594   END SUBROUTINE iom_rp0d_sp 
     1595 
     1596   SUBROUTINE iom_rp0d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1597      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
     1598      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
     1599      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
     1600      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
     1601      REAL(dp)        , INTENT(in)                         ::   pvar     ! written field 
     1602      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
     1603      LOGICAL, OPTIONAL :: ldxios   ! xios write flag 
     1604      LOGICAL :: llx                ! local xios write flag 
     1605      INTEGER :: ivid   ! variable id 
     1606 
     1607      llx = .FALSE. 
     1608      IF(PRESENT(ldxios)) llx = ldxios 
     1609      IF( llx ) THEN 
     1610#ifdef key_iomput 
    14871611      IF( kt == kwrite ) THEN 
    14881612          IF(lwp) write(numout,*) 'RESTART: write (XIOS 0D) ',trim(cdvar) 
     
    14981622         ENDIF 
    14991623      ENDIF 
    1500    END SUBROUTINE iom_rp0d 
    1501  
    1502    SUBROUTINE iom_rp1d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1624   END SUBROUTINE iom_rp0d_dp 
     1625 
     1626 
     1627   SUBROUTINE iom_rp1d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
    15031628      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
    15041629      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
    15051630      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
    15061631      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
    1507       REAL(wp)        , INTENT(in), DIMENSION(          :) ::   pvar     ! written field 
     1632      REAL(sp)        , INTENT(in), DIMENSION(          :) ::   pvar     ! written field 
    15081633      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
    15091634      LOGICAL, OPTIONAL                                    ::   ldxios   ! xios write flag 
     
    15141639      IF(PRESENT(ldxios)) llx = ldxios 
    15151640      IF( llx ) THEN 
    1516 #ifdef key_xios 
     1641#ifdef key_iomput 
     1642      IF( kt == kwrite ) THEN 
     1643         IF(lwp) write(numout,*) 'RESTART: write (XIOS 1D) ',trim(cdvar) 
     1644         CALL xios_send_field(trim(cdvar), pvar) 
     1645      ENDIF 
     1646#endif 
     1647      ELSE 
     1648         IF( kiomid > 0 ) THEN 
     1649            IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1650               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. ) 
     1651               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r1d = real(pvar, dp) ) 
     1652            ENDIF 
     1653         ENDIF 
     1654      ENDIF 
     1655   END SUBROUTINE iom_rp1d_sp 
     1656 
     1657   SUBROUTINE iom_rp1d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1658      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
     1659      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
     1660      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
     1661      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
     1662      REAL(dp)        , INTENT(in), DIMENSION(          :) ::   pvar     ! written field 
     1663      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
     1664      LOGICAL, OPTIONAL                                    ::   ldxios   ! xios write flag 
     1665      LOGICAL :: llx                ! local xios write flag 
     1666      INTEGER :: ivid   ! variable id 
     1667 
     1668      llx = .FALSE. 
     1669      IF(PRESENT(ldxios)) llx = ldxios 
     1670      IF( llx ) THEN 
     1671#ifdef key_iomput 
    15171672      IF( kt == kwrite ) THEN 
    15181673         IF(lwp) write(numout,*) 'RESTART: write (XIOS 1D) ',trim(cdvar) 
     
    15281683         ENDIF 
    15291684      ENDIF 
    1530    END SUBROUTINE iom_rp1d 
    1531  
    1532    SUBROUTINE iom_rp2d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1685   END SUBROUTINE iom_rp1d_dp 
     1686 
     1687 
     1688   SUBROUTINE iom_rp2d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
    15331689      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
    15341690      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
    15351691      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
    15361692      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
    1537       REAL(wp)        , INTENT(in), DIMENSION(:,    :    ) ::   pvar     ! written field 
     1693      REAL(sp)        , INTENT(in), DIMENSION(:,    :    ) ::   pvar     ! written field 
    15381694      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
    15391695      LOGICAL, OPTIONAL :: ldxios   ! xios write flag 
     
    15441700      IF(PRESENT(ldxios)) llx = ldxios 
    15451701      IF( llx ) THEN 
    1546 #ifdef key_xios 
     1702#ifdef key_iomput 
     1703      IF( kt == kwrite ) THEN 
     1704         IF(lwp) write(numout,*) 'RESTART: write (XIOS 2D) ',trim(cdvar) 
     1705         CALL xios_send_field(trim(cdvar), pvar) 
     1706      ENDIF 
     1707#endif 
     1708      ELSE 
     1709         IF( kiomid > 0 ) THEN 
     1710            IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1711               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. ) 
     1712               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r2d = real(pvar, dp) ) 
     1713            ENDIF 
     1714         ENDIF 
     1715      ENDIF 
     1716   END SUBROUTINE iom_rp2d_sp 
     1717 
     1718   SUBROUTINE iom_rp2d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1719      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
     1720      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
     1721      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
     1722      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
     1723      REAL(dp)        , INTENT(in), DIMENSION(:,    :    ) ::   pvar     ! written field 
     1724      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
     1725      LOGICAL, OPTIONAL :: ldxios   ! xios write flag 
     1726      LOGICAL :: llx 
     1727      INTEGER :: ivid   ! variable id 
     1728 
     1729      llx = .FALSE. 
     1730      IF(PRESENT(ldxios)) llx = ldxios 
     1731      IF( llx ) THEN 
     1732#ifdef key_iomput 
    15471733      IF( kt == kwrite ) THEN 
    15481734         IF(lwp) write(numout,*) 'RESTART: write (XIOS 2D) ',trim(cdvar) 
     
    15581744         ENDIF 
    15591745      ENDIF 
    1560    END SUBROUTINE iom_rp2d 
    1561  
    1562    SUBROUTINE iom_rp3d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1746   END SUBROUTINE iom_rp2d_dp 
     1747 
     1748 
     1749   SUBROUTINE iom_rp3d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
    15631750      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
    15641751      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
    15651752      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
    15661753      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
    1567       REAL(wp)        , INTENT(in),       DIMENSION(:,:,:) ::   pvar     ! written field 
     1754      REAL(sp)        , INTENT(in),       DIMENSION(:,:,:) ::   pvar     ! written field 
    15681755      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
    15691756      LOGICAL, OPTIONAL :: ldxios   ! xios write flag 
     
    15741761      IF(PRESENT(ldxios)) llx = ldxios 
    15751762      IF( llx ) THEN 
    1576 #ifdef key_xios 
     1763#ifdef key_iomput 
     1764      IF( kt == kwrite ) THEN 
     1765         IF(lwp) write(numout,*) 'RESTART: write (XIOS 3D) ',trim(cdvar) 
     1766         CALL xios_send_field(trim(cdvar), pvar) 
     1767      ENDIF 
     1768#endif 
     1769      ELSE 
     1770         IF( kiomid > 0 ) THEN 
     1771            IF( iom_file(kiomid)%nfid > 0 ) THEN 
     1772               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. ) 
     1773               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r3d = real(pvar, dp) ) 
     1774            ENDIF 
     1775         ENDIF 
     1776      ENDIF 
     1777   END SUBROUTINE iom_rp3d_sp 
     1778 
     1779   SUBROUTINE iom_rp3d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios ) 
     1780      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step 
     1781      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step 
     1782      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file  
     1783      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name 
     1784      REAL(dp)        , INTENT(in),       DIMENSION(:,:,:) ::   pvar     ! written field 
     1785      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type 
     1786      LOGICAL, OPTIONAL :: ldxios   ! xios write flag 
     1787      LOGICAL :: llx                 ! local xios write flag 
     1788      INTEGER :: ivid   ! variable id 
     1789 
     1790      llx = .FALSE. 
     1791      IF(PRESENT(ldxios)) llx = ldxios 
     1792      IF( llx ) THEN 
     1793#ifdef key_iomput 
    15771794      IF( kt == kwrite ) THEN 
    15781795         IF(lwp) write(numout,*) 'RESTART: write (XIOS 3D) ',trim(cdvar) 
     
    15881805         ENDIF 
    15891806      ENDIF 
    1590    END SUBROUTINE iom_rp3d 
     1807   END SUBROUTINE iom_rp3d_dp 
     1808 
    15911809 
    15921810 
     
    16401858   !!                   INTERFACE iom_put 
    16411859   !!---------------------------------------------------------------------- 
    1642    SUBROUTINE iom_p0d( cdname, pfield0d ) 
     1860   SUBROUTINE iom_p0d_sp( cdname, pfield0d ) 
    16431861      CHARACTER(LEN=*), INTENT(in) ::   cdname 
    1644       REAL(wp)        , INTENT(in) ::   pfield0d 
    1645       REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson 
    1646 #if defined key_xios 
    1647       zz(:,:)=pfield0d 
    1648       CALL xios_send_field(cdname, zz) 
    1649       !CALL xios_send_field(cdname, (/pfield0d/))  
     1862      REAL(sp)        , INTENT(in) ::   pfield0d 
     1863!!      REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson 
     1864#if defined key_iomput 
     1865!!clem      zz(:,:)=pfield0d 
     1866!!clem      CALL xios_send_field(cdname, zz) 
     1867      CALL xios_send_field(cdname, (/pfield0d/))  
    16501868#else 
    16511869      IF( .FALSE. )   WRITE(numout,*) cdname, pfield0d   ! useless test to avoid compilation warnings 
    16521870#endif 
    1653    END SUBROUTINE iom_p0d 
    1654  
    1655    SUBROUTINE iom_p1d( cdname, pfield1d ) 
     1871   END SUBROUTINE iom_p0d_sp 
     1872 
     1873   SUBROUTINE iom_p0d_dp( cdname, pfield0d ) 
     1874      CHARACTER(LEN=*), INTENT(in) ::   cdname 
     1875      REAL(dp)        , INTENT(in) ::   pfield0d 
     1876!!      REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson 
     1877#if defined key_iomput 
     1878!!clem      zz(:,:)=pfield0d 
     1879!!clem      CALL xios_send_field(cdname, zz) 
     1880      CALL xios_send_field(cdname, (/pfield0d/))  
     1881#else 
     1882      IF( .FALSE. )   WRITE(numout,*) cdname, pfield0d   ! useless test to avoid compilation warnings 
     1883#endif 
     1884   END SUBROUTINE iom_p0d_dp 
     1885 
     1886 
     1887   SUBROUTINE iom_p1d_sp( cdname, pfield1d ) 
    16561888      CHARACTER(LEN=*)          , INTENT(in) ::   cdname 
    1657       REAL(wp),     DIMENSION(:), INTENT(in) ::   pfield1d 
    1658 #if defined key_xios 
     1889      REAL(sp),     DIMENSION(:), INTENT(in) ::   pfield1d 
     1890#if defined key_iomput 
    16591891      CALL xios_send_field( cdname, RESHAPE( (/pfield1d/), (/1,1,SIZE(pfield1d)/) ) ) 
    16601892#else 
    16611893      IF( .FALSE. )   WRITE(numout,*) cdname, pfield1d   ! useless test to avoid compilation warnings 
    16621894#endif 
    1663    END SUBROUTINE iom_p1d 
    1664  
    1665    SUBROUTINE iom_p2d( cdname, pfield2d ) 
     1895   END SUBROUTINE iom_p1d_sp 
     1896 
     1897   SUBROUTINE iom_p1d_dp( cdname, pfield1d ) 
     1898      CHARACTER(LEN=*)          , INTENT(in) ::   cdname 
     1899      REAL(dp),     DIMENSION(:), INTENT(in) ::   pfield1d 
     1900#if defined key_iomput 
     1901      CALL xios_send_field( cdname, RESHAPE( (/pfield1d/), (/1,1,SIZE(pfield1d)/) ) ) 
     1902#else 
     1903      IF( .FALSE. )   WRITE(numout,*) cdname, pfield1d   ! useless test to avoid compilation warnings 
     1904#endif 
     1905   END SUBROUTINE iom_p1d_dp 
     1906 
     1907   SUBROUTINE iom_p2d_sp( cdname, pfield2d ) 
    16661908      CHARACTER(LEN=*)            , INTENT(in) ::   cdname 
    1667       REAL(wp),     DIMENSION(:,:), INTENT(in) ::   pfield2d 
    1668 #if defined key_xios 
    1669       CALL xios_send_field(cdname, pfield2d) 
     1909      REAL(sp),     DIMENSION(:,:), INTENT(in) ::   pfield2d 
     1910      IF( iom_use(cdname) ) THEN 
     1911#if defined key_iomput 
     1912         IF( SIZE(pfield2d, dim=1) == jpi .AND. SIZE(pfield2d, dim=2) == jpj ) THEN 
     1913            CALL xios_send_field( cdname, pfield2d(Nis0:Nie0, Njs0:Nje0) )       ! this extraction will create a copy of pfield2d 
     1914         ELSE 
     1915            CALL xios_send_field( cdname, pfield2d ) 
     1916         ENDIF 
    16701917#else 
    1671       IF( .FALSE. )   WRITE(numout,*) cdname, pfield2d   ! useless test to avoid compilation warnings 
    1672 #endif 
    1673    END SUBROUTINE iom_p2d 
    1674  
    1675    SUBROUTINE iom_p3d( cdname, pfield3d ) 
     1918         WRITE(numout,*) pfield2d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings 
     1919#endif 
     1920      ENDIF 
     1921   END SUBROUTINE iom_p2d_sp 
     1922 
     1923   SUBROUTINE iom_p2d_dp( cdname, pfield2d ) 
     1924      CHARACTER(LEN=*)            , INTENT(in) ::   cdname 
     1925      REAL(dp),     DIMENSION(:,:), INTENT(in) ::   pfield2d 
     1926      IF( iom_use(cdname) ) THEN 
     1927#if defined key_iomput 
     1928         IF( SIZE(pfield2d, dim=1) == jpi .AND. SIZE(pfield2d, dim=2) == jpj ) THEN 
     1929            CALL xios_send_field( cdname, pfield2d(Nis0:Nie0, Njs0:Nje0) )       ! this extraction will create a copy of pfield2d 
     1930         ELSE 
     1931            CALL xios_send_field( cdname, pfield2d ) 
     1932         ENDIF 
     1933#else 
     1934         WRITE(numout,*) pfield2d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings 
     1935#endif 
     1936      ENDIF 
     1937   END SUBROUTINE iom_p2d_dp 
     1938 
     1939   SUBROUTINE iom_p3d_sp( cdname, pfield3d ) 
    16761940      CHARACTER(LEN=*)                , INTENT(in) ::   cdname 
    1677       REAL(wp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d 
    1678 #if defined key_xios 
    1679       CALL xios_send_field( cdname, pfield3d ) 
     1941      REAL(sp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d 
     1942      IF( iom_use(cdname) ) THEN 
     1943#if defined key_iomput 
     1944         IF( SIZE(pfield3d, dim=1) == jpi .AND. SIZE(pfield3d, dim=2) == jpj ) THEN 
     1945            CALL xios_send_field( cdname, pfield3d(Nis0:Nie0, Njs0:Nje0,:) )     ! this extraction will create a copy of pfield3d 
     1946         ELSE 
     1947            CALL xios_send_field( cdname, pfield3d ) 
     1948         ENDIF 
    16801949#else 
    1681       IF( .FALSE. )   WRITE(numout,*) cdname, pfield3d   ! useless test to avoid compilation warnings 
    1682 #endif 
    1683    END SUBROUTINE iom_p3d 
    1684  
    1685 #if defined key_xios 
     1950         WRITE(numout,*) pfield3d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings 
     1951#endif 
     1952      ENDIF 
     1953   END SUBROUTINE iom_p3d_sp 
     1954 
     1955   SUBROUTINE iom_p3d_dp( cdname, pfield3d ) 
     1956      CHARACTER(LEN=*)                , INTENT(in) ::   cdname 
     1957      REAL(dp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d 
     1958      IF( iom_use(cdname) ) THEN 
     1959#if defined key_iomput 
     1960         IF( SIZE(pfield3d, dim=1) == jpi .AND. SIZE(pfield3d, dim=2) == jpj ) THEN 
     1961            CALL xios_send_field( cdname, pfield3d(Nis0:Nie0, Njs0:Nje0,:) )     ! this extraction will create a copy of pfield3d 
     1962         ELSE 
     1963            CALL xios_send_field( cdname, pfield3d ) 
     1964         ENDIF 
     1965#else 
     1966         WRITE(numout,*) pfield3d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings 
     1967#endif 
     1968      ENDIF 
     1969   END SUBROUTINE iom_p3d_dp 
     1970 
     1971   SUBROUTINE iom_p4d_sp( cdname, pfield4d ) 
     1972      CHARACTER(LEN=*)                , INTENT(in) ::   cdname 
     1973      REAL(sp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d 
     1974      IF( iom_use(cdname) ) THEN 
     1975#if defined key_iomput 
     1976         IF( SIZE(pfield4d, dim=1) == jpi .AND. SIZE(pfield4d, dim=2) == jpj ) THEN 
     1977            CALL xios_send_field( cdname, pfield4d(Nis0:Nie0, Njs0:Nje0,:,:) )   ! this extraction will create a copy of pfield4d 
     1978         ELSE 
     1979            CALL xios_send_field (cdname, pfield4d ) 
     1980         ENDIF 
     1981#else 
     1982         WRITE(numout,*) pfield4d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings 
     1983#endif 
     1984      ENDIF 
     1985   END SUBROUTINE iom_p4d_sp 
     1986 
     1987   SUBROUTINE iom_p4d_dp( cdname, pfield4d ) 
     1988      CHARACTER(LEN=*)                , INTENT(in) ::   cdname 
     1989      REAL(dp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d 
     1990      IF( iom_use(cdname) ) THEN 
     1991#if defined key_iomput 
     1992         IF( SIZE(pfield4d, dim=1) == jpi .AND. SIZE(pfield4d, dim=2) == jpj ) THEN 
     1993            CALL xios_send_field( cdname, pfield4d(Nis0:Nie0, Njs0:Nje0,:,:) )   ! this extraction will create a copy of pfield4d 
     1994         ELSE 
     1995            CALL xios_send_field (cdname, pfield4d ) 
     1996         ENDIF 
     1997#else 
     1998         WRITE(numout,*) pfield4d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings 
     1999#endif 
     2000      ENDIF 
     2001   END SUBROUTINE iom_p4d_dp 
     2002 
     2003#if defined key_iomput 
    16862004   !!---------------------------------------------------------------------- 
    1687    !!   'key_xios'                                         XIOS interface 
     2005   !!   'key_iomput'                                         XIOS interface 
    16882006   !!---------------------------------------------------------------------- 
    16892007 
     
    16972015      INTEGER                 , OPTIONAL, INTENT(in) ::   data_dim, data_ibegin, data_ni, data_jbegin, data_nj 
    16982016      INTEGER                 , OPTIONAL, INTENT(in) ::   nvertex 
    1699       REAL(wp), DIMENSION(:)  , OPTIONAL, INTENT(in) ::   lonvalue, latvalue 
    1700       REAL(wp), DIMENSION(:,:), OPTIONAL, INTENT(in) ::   bounds_lon, bounds_lat, area 
     2017      REAL(dp), DIMENSION(:)  , OPTIONAL, INTENT(in) ::   lonvalue, latvalue 
     2018      REAL(dp), DIMENSION(:,:), OPTIONAL, INTENT(in) ::   bounds_lon, bounds_lat, area 
    17012019      LOGICAL , DIMENSION(:)  , OPTIONAL, INTENT(in) ::   mask 
    17022020      !!---------------------------------------------------------------------- 
     
    17612079      !!---------------------------------------------------------------------- 
    17622080      IF( PRESENT(paxis) ) THEN 
    1763          IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, n_glo=SIZE(paxis), value=paxis ) 
    1764          IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, n_glo=SIZE(paxis), value=paxis ) 
    1765       ENDIF 
    1766       IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, bounds=bounds ) 
    1767       IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, bounds=bounds ) 
     2081         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, n_glo=SIZE(paxis), value=real(paxis, dp) ) 
     2082         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, n_glo=SIZE(paxis), value=real(paxis, dp) ) 
     2083      ENDIF 
     2084      IF( PRESENT(bounds) ) THEN 
     2085         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, bounds=real(bounds, dp) ) 
     2086         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, bounds=real(bounds, dp) ) 
     2087      ELSE 
     2088         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid) 
     2089         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid) 
     2090      END IF 
    17682091      CALL xios_solve_inheritance() 
    17692092   END SUBROUTINE iom_set_axis_attr 
     
    18722195      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   plat 
    18732196      ! 
    1874       INTEGER  :: ni, nj 
    18752197      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zmask 
    18762198      LOGICAL, INTENT(IN) :: ldxios, ldrxios 
    18772199      !!---------------------------------------------------------------------- 
    18782200      ! 
    1879       ni = nlei-nldi+1 
    1880       nj = nlej-nldj+1 
    1881       ! 
    1882       CALL iom_set_domain_attr("grid_"//cdgrd, ni_glo=jpiglo, nj_glo=jpjglo, ibegin=nimpp+nldi-2, jbegin=njmpp+nldj-2, ni=ni, nj=nj) 
    1883       CALL iom_set_domain_attr("grid_"//cdgrd, data_dim=2, data_ibegin = 1-nldi, data_ni = jpi, data_jbegin = 1-nldj, data_nj = jpj) 
     2201      CALL iom_set_domain_attr("grid_"//cdgrd, ni_glo=Ni0glo,nj_glo=Nj0glo,ibegin=mig0(Nis0)-1,jbegin=mjg0(Njs0)-1,ni=Ni_0,nj=Nj_0) 
     2202      CALL iom_set_domain_attr("grid_"//cdgrd, data_dim=2, data_ibegin = 0, data_ni = Ni_0, data_jbegin = 0, data_nj = Nj_0) 
    18842203!don't define lon and lat for restart reading context.  
    18852204      IF ( .NOT.ldrxios ) & 
    1886          CALL iom_set_domain_attr("grid_"//cdgrd, lonvalue = RESHAPE(plon(nldi:nlei, nldj:nlej),(/ ni*nj /)),   & 
    1887          &                                     latvalue = RESHAPE(plat(nldi:nlei, nldj:nlej),(/ ni*nj /)))   
     2205         CALL iom_set_domain_attr("grid_"//cdgrd, lonvalue = real(RESHAPE(plon(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp),   & 
     2206         &                                        latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp ))   
    18882207      ! 
    18892208      IF ( ln_mskland .AND. (.NOT.ldxios) ) THEN 
     
    18912210         SELECT CASE ( cdgrd ) 
    18922211         CASE('T')   ;   zmask(:,:,:)       = tmask(:,:,:) 
    1893          CASE('U')   ;   zmask(2:jpim1,:,:) = tmask(2:jpim1,:,:) + tmask(3:jpi,:,:)   ;   CALL lbc_lnk( 'iom', zmask, 'U', 1. ) 
    1894          CASE('V')   ;   zmask(:,2:jpjm1,:) = tmask(:,2:jpjm1,:) + tmask(:,3:jpj,:)   ;   CALL lbc_lnk( 'iom', zmask, 'V', 1. ) 
     2212         CASE('U')   ;   zmask(2:jpim1,:,:) = tmask(2:jpim1,:,:) + tmask(3:jpi,:,:) 
     2213         CASE('V')   ;   zmask(:,2:jpjm1,:) = tmask(:,2:jpjm1,:) + tmask(:,3:jpj,:) 
    18952214         CASE('W')   ;   zmask(:,:,2:jpk  ) = tmask(:,:,1:jpkm1) + tmask(:,:,2:jpk)   ;   zmask(:,:,1) = tmask(:,:,1) 
    18962215         END SELECT 
    18972216         ! 
    1898          CALL iom_set_domain_attr( "grid_"//cdgrd       , mask = RESHAPE(zmask(nldi:nlei,nldj:nlej,1),(/ni*nj    /)) /= 0. ) 
    1899          CALL iom_set_grid_attr  ( "grid_"//cdgrd//"_3D", mask = RESHAPE(zmask(nldi:nlei,nldj:nlej,:),(/ni,nj,jpk/)) /= 0. ) 
     2217         CALL iom_set_domain_attr( "grid_"//cdgrd       , mask = RESHAPE(zmask(Nis0:Nie0,Njs0:Nje0,1),(/Ni_0*Nj_0    /)) /= 0. ) 
     2218         CALL iom_set_grid_attr  ( "grid_"//cdgrd//"_3D", mask = RESHAPE(zmask(Nis0:Nie0,Njs0:Nje0,:),(/Ni_0,Nj_0,jpk/)) /= 0. ) 
    19002219      ENDIF 
    19012220      ! 
    19022221   END SUBROUTINE set_grid 
    1903  
    19042222 
    19052223   SUBROUTINE set_grid_bounds( cdgrd, plon_cnr, plat_cnr, plon_pnt, plat_pnt ) 
     
    19142232      REAL(wp), DIMENSION(jpi,jpj), OPTIONAL, INTENT(in) :: plon_pnt, plat_pnt  ! Lat/lon coord. of the point of cell (i,j) 
    19152233      ! 
    1916       INTEGER :: ji, jj, jn, ni, nj 
    1917       INTEGER :: icnr, jcnr                                    ! Offset such that the vertex coordinate (i+icnr,j+jcnr) 
    1918       !                                                        ! represents the bottom-left corner of cell (i,j) 
     2234      INTEGER :: ji, jj, jn 
     2235      INTEGER :: icnr, jcnr                             ! Offset such that the vertex coordinate (i+icnr,j+jcnr) 
     2236      !                                                 ! represents the 
     2237      !                                                 bottom-left corner of 
     2238      !                                                 cell (i,j) 
    19192239      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: z_bnds      ! Lat/lon coordinates of the vertices of cell (i,j) 
    19202240      REAL(wp), ALLOCATABLE, DIMENSION(:,:)     :: z_fld       ! Working array to determine where to rotate cells 
     
    19312251      END SELECT 
    19322252      ! 
    1933       ni = nlei-nldi+1   ! Dimensions of subdomain interior 
    1934       nj = nlej-nldj+1 
    1935       ! 
    19362253      z_fld(:,:) = 1._wp 
    1937       CALL lbc_lnk( 'iom', z_fld, cdgrd, -1. )    ! Working array for location of northfold 
     2254      CALL lbc_lnk( 'iom', z_fld, cdgrd, -1.0_wp )    ! Working array for location of northfold 
    19382255      ! 
    19392256      ! Cell vertices that can be defined 
    1940       DO jj = 2, jpjm1 
    1941          DO ji = 2, jpim1 
    1942             z_bnds(1,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left 
    1943             z_bnds(2,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right 
    1944             z_bnds(3,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right 
    1945             z_bnds(4,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr+1) ! Top-left 
    1946             z_bnds(1,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left 
    1947             z_bnds(2,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right 
    1948             z_bnds(3,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right 
    1949             z_bnds(4,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr+1) ! Top-left 
    1950          END DO 
    1951       END DO 
    1952       ! 
    1953       ! Cell vertices on boundries 
    1954       DO jn = 1, 4 
    1955          CALL lbc_lnk( 'iom', z_bnds(jn,:,:,1), cdgrd, 1., pval=999._wp ) 
    1956          CALL lbc_lnk( 'iom', z_bnds(jn,:,:,2), cdgrd, 1., pval=999._wp ) 
    1957       END DO 
    1958       ! 
    1959       ! Zero-size cells at closed boundaries if cell points provided, 
    1960       ! otherwise they are closed cells with unrealistic bounds 
    1961       IF( PRESENT(plon_pnt) .AND. PRESENT(plat_pnt) ) THEN 
    1962          IF( (nbondi == -1 .OR. nbondi == 2) .AND. .NOT. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6) ) THEN 
    1963             DO jn = 1, 4        ! (West or jpni = 1), closed E-W 
    1964                z_bnds(jn,1,:,1) = plat_pnt(1,:)  ;  z_bnds(jn,1,:,2) = plon_pnt(1,:) 
    1965             END DO 
    1966          ENDIF 
    1967          IF( (nbondi == 1 .OR. nbondi == 2) .AND. .NOT. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6) ) THEN 
    1968             DO jn = 1, 4        ! (East or jpni = 1), closed E-W 
    1969                z_bnds(jn,nlci,:,1) = plat_pnt(nlci,:)  ;  z_bnds(jn,nlci,:,2) = plon_pnt(nlci,:) 
    1970             END DO 
    1971          ENDIF 
    1972          IF( nbondj == -1 .OR. (nbondj == 2 .AND. jperio /= 2) ) THEN 
    1973             DO jn = 1, 4        ! South or (jpnj = 1, not symmetric) 
    1974                z_bnds(jn,:,1,1) = plat_pnt(:,1)  ;  z_bnds(jn,:,1,2) = plon_pnt(:,1) 
    1975             END DO 
    1976          ENDIF 
    1977          IF( (nbondj == 1 .OR. nbondj == 2) .AND. jperio  < 3 ) THEN 
    1978             DO jn = 1, 4        ! (North or jpnj = 1), no north fold 
    1979                z_bnds(jn,:,nlcj,1) = plat_pnt(:,nlcj)  ;  z_bnds(jn,:,nlcj,2) = plon_pnt(:,nlcj) 
    1980             END DO 
    1981          ENDIF 
    1982       ENDIF 
    1983       ! 
    1984       IF( (nbondj == 1 .OR. nbondj == 2) .AND. jperio >= 3 ) THEN    ! Rotate cells at the north fold 
    1985          DO jj = 1, jpj 
    1986             DO ji = 1, jpi 
    1987                IF( z_fld(ji,jj) == -1. ) THEN 
    1988                   z_rot(1,:) = z_bnds(3,ji,jj,:) ; z_rot(2,:) = z_bnds(4,ji,jj,:) 
    1989                   z_rot(3,:) = z_bnds(1,ji,jj,:) ; z_rot(4,:) = z_bnds(2,ji,jj,:) 
    1990                   z_bnds(:,ji,jj,:) = z_rot(:,:) 
    1991                ENDIF 
    1992             END DO 
    1993          END DO 
    1994       ELSE IF( nbondj == 2 .AND. jperio == 2 ) THEN                  ! Invert cells at the symmetric equator 
    1995          DO ji = 1, jpi 
    1996             z_rot(1:2,:) = z_bnds(3:4,ji,1,:) 
    1997             z_rot(3:4,:) = z_bnds(1:2,ji,1,:) 
    1998             z_bnds(:,ji,1,:) = z_rot(:,:) 
    1999          END DO 
    2000       ENDIF 
    2001       ! 
    2002       CALL iom_set_domain_attr("grid_"//cdgrd, bounds_lat = RESHAPE(z_bnds(:,nldi:nlei,nldj:nlej,1),(/ 4,ni*nj /)),           & 
    2003           &                                    bounds_lon = RESHAPE(z_bnds(:,nldi:nlei,nldj:nlej,2),(/ 4,ni*nj /)), nvertex=4 ) 
    2004       ! 
    2005       DEALLOCATE( z_bnds, z_fld, z_rot )  
     2257      DO_2D( 0, 0, 0, 0 ) 
     2258         z_bnds(1,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left 
     2259         z_bnds(2,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right 
     2260         z_bnds(3,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right 
     2261         z_bnds(4,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr+1) ! Top-left 
     2262         z_bnds(1,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left 
     2263         z_bnds(2,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right 
     2264         z_bnds(3,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right 
     2265         z_bnds(4,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr+1) ! Top-left 
     2266      END_2D 
     2267      ! 
     2268      DO_2D( 0, 0, 0, 0 ) 
     2269         IF( z_fld(ji,jj) == -1. ) THEN 
     2270            z_rot(1,:) = z_bnds(3,ji,jj,:) ; z_rot(2,:) = z_bnds(4,ji,jj,:) 
     2271            z_rot(3,:) = z_bnds(1,ji,jj,:) ; z_rot(4,:) = z_bnds(2,ji,jj,:) 
     2272            z_bnds(:,ji,jj,:) = z_rot(:,:) 
     2273         ENDIF 
     2274      END_2D 
     2275      ! 
     2276      CALL iom_set_domain_attr("grid_"//cdgrd, bounds_lat = real(RESHAPE(z_bnds(:,Nis0:Nie0,Njs0:Nje0,1),(/ 4,Ni_0*Nj_0 /)), dp),           & 
     2277          &                                    bounds_lon = real(RESHAPE(z_bnds(:,Nis0:Nie0,Njs0:Nje0,2),(/ 4,Ni_0*Nj_0 /)), dp), nvertex=4 ) 
     2278      ! 
     2279      DEALLOCATE( z_bnds, z_fld, z_rot ) 
    20062280      ! 
    20072281   END SUBROUTINE set_grid_bounds 
    20082282 
    2009  
    20102283   SUBROUTINE set_grid_znl( plat ) 
    20112284      !!---------------------------------------------------------------------- 
     
    20172290      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   plat 
    20182291      ! 
    2019       INTEGER  :: ni, nj, ix, iy 
     2292      INTEGER  :: ix, iy 
    20202293      REAL(wp), DIMENSION(:), ALLOCATABLE  ::   zlon 
    20212294      !!---------------------------------------------------------------------- 
    20222295      ! 
    2023       ni=nlei-nldi+1       ! define zonal mean domain (jpj*jpk) 
    2024       nj=nlej-nldj+1 
    2025       ALLOCATE( zlon(ni*nj) )       ;       zlon(:) = 0._wp 
    2026       ! 
    2027       CALL dom_ngb( -168.53, 65.03, ix, iy, 'T' ) !  i-line that passes through Bering Strait: Reference latitude (used in plots) 
    2028 !      CALL dom_ngb( 180., 90., ix, iy, 'T' ) !  i-line that passes near the North Pole : Reference latitude (used in plots) 
    2029       CALL iom_set_domain_attr("gznl", ni_glo=jpiglo, nj_glo=jpjglo, ibegin=nimpp+nldi-2, jbegin=njmpp+nldj-2, ni=ni, nj=nj) 
    2030       CALL iom_set_domain_attr("gznl", data_dim=2, data_ibegin = 1-nldi, data_ni = jpi, data_jbegin = 1-nldj, data_nj = jpj) 
    2031       CALL iom_set_domain_attr("gznl", lonvalue = zlon,   & 
    2032          &                             latvalue = RESHAPE(plat(nldi:nlei, nldj:nlej),(/ ni*nj /)))   
    2033       CALL iom_set_zoom_domain_attr("znl_T", ibegin=ix-1, jbegin=0, ni=1, nj=jpjglo) 
    2034       CALL iom_set_zoom_domain_attr("znl_W", ibegin=ix-1, jbegin=0, ni=1, nj=jpjglo) 
     2296      ALLOCATE( zlon(Ni_0*Nj_0) )       ;       zlon(:) = 0._wp 
     2297      ! 
     2298!      CALL dom_ngb( -168.53_wp, 65.03_wp, ix, iy, 'T' ) !  i-line that passes through Bering Strait: Reference latitude (used in plots) 
     2299      CALL dom_ngb( 180.0_wp, 90.0_wp, ix, iy, 'T' ) !  i-line that passes near the North Pole : Reference latitude (used in plots) 
     2300      CALL iom_set_domain_attr("gznl", ni_glo=Ni0glo, nj_glo=Nj0glo, ibegin=mig0(Nis0)-1, jbegin=mjg0(Njs0)-1, ni=Ni_0, nj=Nj_0) 
     2301      CALL iom_set_domain_attr("gznl", data_dim=2, data_ibegin = 0, data_ni = Ni_0, data_jbegin = 0, data_nj = Nj_0) 
     2302      CALL iom_set_domain_attr("gznl", lonvalue = real(zlon, dp),   & 
     2303         &                             latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp))   
     2304      CALL iom_set_zoom_domain_attr("ptr", ibegin=ix-1, jbegin=0, ni=1, nj=Nj_0) 
    20352305      ! 
    20362306      CALL iom_update_file_name('ptr') 
     
    20462316      !! 
    20472317      !!---------------------------------------------------------------------- 
    2048       REAL(wp), DIMENSION(1)   ::   zz = 1. 
     2318      REAL(dp), DIMENSION(1)   ::   zz = 1. 
    20492319      !!---------------------------------------------------------------------- 
    20502320      ! 
     
    20872357      f_op%timestep = nn_fsbc  ;  f_of%timestep =  0  ; CALL iom_set_field_attr('SBC'             , freq_op=f_op, freq_offset=f_of) 
    20882358      f_op%timestep = nn_fsbc  ;  f_of%timestep =  0  ; CALL iom_set_field_attr('SBC_scalar'      , freq_op=f_op, freq_offset=f_of) 
    2089       f_op%timestep = nn_dttrc ;  f_of%timestep =  0  ; CALL iom_set_field_attr('ptrc_T'          , freq_op=f_op, freq_offset=f_of) 
    2090       f_op%timestep = nn_dttrc ;  f_of%timestep =  0  ; CALL iom_set_field_attr('diad_T'          , freq_op=f_op, freq_offset=f_of) 
     2359      f_op%timestep = nn_fsbc  ;  f_of%timestep =  0  ; CALL iom_set_field_attr('ABL'             , freq_op=f_op, freq_offset=f_of) 
    20912360 
    20922361      ! output file names (attribut: name) 
     
    21092378         cl1 = clgrd(jg) 
    21102379         ! Equatorial section (attributs: jbegin, ni, name_suffix) 
    2111          CALL dom_ngb( 0., 0., ix, iy, cl1 ) 
    2112          CALL iom_set_zoom_domain_attr('Eq'//cl1, ibegin=0, jbegin=iy-1, ni=jpiglo, nj=1 ) 
     2380         CALL dom_ngb( 0.0_wp, 0.0_wp, ix, iy, cl1 ) 
     2381         CALL iom_set_zoom_domain_attr('Eq'//cl1, ibegin=0, jbegin=iy-1, ni=Ni0glo, nj=1 ) 
    21132382         CALL iom_get_file_attr   ('Eq'//cl1, name_suffix = clsuff             ) 
    21142383         CALL iom_set_file_attr   ('Eq'//cl1, name_suffix = TRIM(clsuff)//'_Eq') 
     
    22692538            idx = INDEX(clname,'@startdate@') + INDEX(clname,'@STARTDATE@') 
    22702539            DO WHILE ( idx /= 0 )  
    2271                cldate = iom_sdate( fjulday - rdt / rday ) 
     2540               cldate = iom_sdate( fjulday - rn_Dt / rday ) 
    22722541               clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+11:LEN_TRIM(clname)) 
    22732542               idx = INDEX(clname,'@startdate@') + INDEX(clname,'@STARTDATE@') 
     
    22762545            idx = INDEX(clname,'@startdatefull@') + INDEX(clname,'@STARTDATEFULL@') 
    22772546            DO WHILE ( idx /= 0 )  
    2278                cldate = iom_sdate( fjulday - rdt / rday, ldfull = .TRUE. ) 
     2547               cldate = iom_sdate( fjulday - rn_Dt / rday, ldfull = .TRUE. ) 
    22792548               clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+15:LEN_TRIM(clname)) 
    22802549               idx = INDEX(clname,'@startdatefull@') + INDEX(clname,'@STARTDATEFULL@') 
     
    22832552            idx = INDEX(clname,'@enddate@') + INDEX(clname,'@ENDDATE@') 
    22842553            DO WHILE ( idx /= 0 )  
    2285                cldate = iom_sdate( fjulday + rdt / rday * REAL( nitend - nit000, wp ), ld24 = .TRUE. ) 
     2554               cldate = iom_sdate( fjulday + rn_Dt / rday * REAL( nitend - nit000, wp ), ld24 = .TRUE. ) 
    22862555               clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+9:LEN_TRIM(clname)) 
    22872556               idx = INDEX(clname,'@enddate@') + INDEX(clname,'@ENDDATE@') 
     
    22902559            idx = INDEX(clname,'@enddatefull@') + INDEX(clname,'@ENDDATEFULL@') 
    22912560            DO WHILE ( idx /= 0 )  
    2292                cldate = iom_sdate( fjulday + rdt / rday * REAL( nitend - nit000, wp ), ld24 = .TRUE., ldfull = .TRUE. ) 
     2561               cldate = iom_sdate( fjulday + rn_Dt / rday * REAL( nitend - nit000, wp ), ld24 = .TRUE., ldfull = .TRUE. ) 
    22932562               clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+13:LEN_TRIM(clname)) 
    22942563               idx = INDEX(clname,'@enddatefull@') + INDEX(clname,'@ENDDATEFULL@') 
     
    23352604      ! 
    23362605      IF ( ll24 .AND. isec == 0 ) THEN   ! 00:00 of the next day -> move to 24:00 of the current day 
    2337          CALL ju2ymds( pjday - 1., iyear, imonth, iday, zsec ) 
     2606         CALL ju2ymds( pjday - 1.0_wp, iyear, imonth, iday, zsec ) 
    23382607         isec = 86400 
    23392608      ENDIF 
     
    23612630#else 
    23622631   !!---------------------------------------------------------------------- 
    2363    !!   NOT 'key_xios'                               a few dummy routines 
     2632   !!   NOT 'key_iomput'                               a few dummy routines 
    23642633   !!---------------------------------------------------------------------- 
    2365  
    23662634   SUBROUTINE iom_setkt( kt, cdname ) 
    23672635      INTEGER         , INTENT(in)::   kt  
     
    23752643   END SUBROUTINE iom_context_finalize 
    23762644 
     2645   SUBROUTINE iom_update_file_name( cdid ) 
     2646      CHARACTER(LEN=*), INTENT(in) ::   cdid 
     2647      IF( .FALSE. )   WRITE(numout,*)  cdid   ! useless test to avoid compilation warnings 
     2648   END SUBROUTINE iom_update_file_name 
     2649 
    23772650#endif 
    23782651 
    23792652   LOGICAL FUNCTION iom_use( cdname ) 
    2380       !!---------------------------------------------------------------------- 
    2381       !!---------------------------------------------------------------------- 
    23822653      CHARACTER(LEN=*), INTENT(in) ::   cdname 
    2383       !!---------------------------------------------------------------------- 
    2384 #if defined key_xios 
     2654#if defined key_iomput 
    23852655      iom_use = xios_field_is_active( cdname ) 
    23862656#else 
     
    23882658#endif 
    23892659   END FUNCTION iom_use 
    2390     
     2660 
     2661   SUBROUTINE iom_miss_val( cdname, pmiss_val ) 
     2662      CHARACTER(LEN=*), INTENT(in ) ::   cdname 
     2663      REAL(wp)        , INTENT(out) ::   pmiss_val    
     2664      REAL(dp)                      ::   ztmp_pmiss_val    
     2665#if defined key_iomput 
     2666      ! get missing value 
     2667      CALL xios_get_field_attr( cdname, default_value = ztmp_pmiss_val ) 
     2668      pmiss_val = ztmp_pmiss_val 
     2669#else 
     2670      IF( .FALSE. )   WRITE(numout,*) cdname, pmiss_val   ! useless test to avoid compilation warnings 
     2671      IF( .FALSE. )   pmiss_val = 0._wp                   ! useless assignment to avoid compilation warnings 
     2672#endif 
     2673   END SUBROUTINE iom_miss_val 
     2674   
    23912675   !!====================================================================== 
    23922676END MODULE iom 
  • utils/tools/DOMAINcfg/src/iom_def.F90

    r12414 r14623  
    1313   PRIVATE 
    1414 
    15    INTEGER, PARAMETER, PUBLIC ::   jpdom_data          = 1   !: ( 1  :jpiglo, 1  :jpjglo)    !!gm to be suppressed 
    16    INTEGER, PARAMETER, PUBLIC ::   jpdom_global        = 2   !: ( 1  :jpiglo, 1  :jpjglo) 
    17    INTEGER, PARAMETER, PUBLIC ::   jpdom_local         = 3   !: One of the 3 following cases 
    18    INTEGER, PARAMETER, PUBLIC ::   jpdom_local_full    = 4   !: ( 1  :jpi   , 1  :jpi   ) 
    19    INTEGER, PARAMETER, PUBLIC ::   jpdom_local_noextra = 5   !: ( 1  :nlci  , 1  :nlcj  ) 
    20    INTEGER, PARAMETER, PUBLIC ::   jpdom_local_noovlap = 6   !: (nldi:nlei  ,nldj:nlej  ) 
    21    INTEGER, PARAMETER, PUBLIC ::   jpdom_unknown       = 7   !: No dimension checking 
    22    INTEGER, PARAMETER, PUBLIC ::   jpdom_autoglo       = 8   !:  
    23    INTEGER, PARAMETER, PUBLIC ::   jpdom_autoglo_xy    = 9   !: Automatically set horizontal dimensions only 
    24    INTEGER, PARAMETER, PUBLIC ::   jpdom_autodta       = 10  !:  
     15   INTEGER, PARAMETER, PUBLIC ::   jpdom_global        = 1   !: ( 1  :Ni0glo, 1  :Nj0glo) 
     16   INTEGER, PARAMETER, PUBLIC ::   jpdom_local         = 2   !: (Nis0: Nie0 ,Njs0: Nje0 ) 
     17   INTEGER, PARAMETER, PUBLIC ::   jpdom_unknown       = 3   !: No dimension checking 
     18   INTEGER, PARAMETER, PUBLIC ::   jpdom_auto          = 4   !:  
     19   INTEGER, PARAMETER, PUBLIC ::   jpdom_auto_xy       = 5   !: Automatically set horizontal dimensions only 
     20 
     21   INTEGER, PARAMETER, PUBLIC ::   jpdom_data = jpdom_global 
    2522 
    2623   INTEGER, PARAMETER, PUBLIC ::   jp_r8    = 200      !: write REAL(8) 
     
    3330   INTEGER, PARAMETER, PUBLIC ::   jpmax_vars   = 1200 !: maximum number of variables in one file 
    3431   INTEGER, PARAMETER, PUBLIC ::   jpmax_dims   =  4   !: maximum number of dimensions for one variable 
    35    INTEGER, PARAMETER, PUBLIC ::   jpmax_digits =  5   !: maximum number of digits for the cpu number in the file name 
    36  
     32   INTEGER, PARAMETER, PUBLIC ::   jpmax_digits =  9   !: maximum number of digits for the cpu number in the file name 
    3733 
    3834!$AGRIF_DO_NOT_TREAT 
     
    4642   LOGICAL, PUBLIC            ::   lxios_set  = .FALSE.  
    4743 
    48  
    49  
    5044   TYPE, PUBLIC ::   file_descriptor 
    5145      CHARACTER(LEN=240)                        ::   name     !: name of the file 
     46      CHARACTER(LEN=3  )                        ::   comp     !: name of component opening the file ('OCE', 'ICE'...) 
    5247      INTEGER                                   ::   nfid     !: identifier of the file (0 if closed) 
    5348                                                              !: jpioipsl option has been removed) 
     
    6459      REAL(kind=wp), DIMENSION(jpmax_vars)      ::   scf      !: scale_factor of the variables 
    6560      REAL(kind=wp), DIMENSION(jpmax_vars)      ::   ofs      !: add_offset of the variables 
    66       INTEGER                                   ::   nlev     ! number of vertical levels 
    6761   END TYPE file_descriptor 
    6862   TYPE(file_descriptor), DIMENSION(jpmax_files), PUBLIC ::   iom_file !: array containing the info for all opened files 
     
    7771   TYPE(RST_FIELD), PUBLIC, SAVE :: rst_wfields(max_rst_fields), rst_rfields(max_rst_fields) 
    7872   ! 
     73   !! * Substitutions 
     74#  include "do_loop_substitute.h90" 
    7975   !!---------------------------------------------------------------------- 
    8076   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    81    !! $Id: iom_def.F90 10425 2018-12-19 21:54:16Z smasson $ 
     77   !! $Id: iom_def.F90 13286 2020-07-09 15:48:29Z smasson $ 
    8278   !! Software governed by the CeCILL license (see ./LICENSE) 
    8379   !!====================================================================== 
  • utils/tools/DOMAINcfg/src/iom_nf90.F90

    r13204 r14623  
    1919   !!---------------------------------------------------------------------- 
    2020   USE dom_oce         ! ocean space and time domain 
     21   !USE sbc_oce, ONLY: ght_abl ! abl vertical level number and height 
    2122   USE lbclnk          ! lateal boundary condition / mpp exchanges 
    2223   USE iom_def         ! iom variables definitions 
     
    3233 
    3334   INTERFACE iom_nf90_get 
    34       MODULE PROCEDURE iom_nf90_g0d, iom_nf90_g123d 
     35      MODULE PROCEDURE iom_nf90_g0d_sp                    
     36      MODULE PROCEDURE iom_nf90_g0d_dp, iom_nf90_g123d_dp 
    3537   END INTERFACE 
    3638   INTERFACE iom_nf90_rstput 
    37       MODULE PROCEDURE iom_nf90_rp0123d 
     39      MODULE PROCEDURE iom_nf90_rp0123d_dp 
    3840   END INTERFACE 
    3941 
    4042   !!---------------------------------------------------------------------- 
    4143   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    42    !! $Id: iom_nf90.F90 10522 2019-01-16 08:35:15Z smasson $ 
     44   !! $Id: iom_nf90.F90 13286 2020-07-09 15:48:29Z smasson $ 
    4345   !! Software governed by the CeCILL license (see ./LICENSE) 
    4446   !!---------------------------------------------------------------------- 
    4547CONTAINS 
    4648 
    47    SUBROUTINE iom_nf90_open( cdname, kiomid, ldwrt, ldok, kdompar, kdlev ) 
     49   SUBROUTINE iom_nf90_open( cdname, kiomid, ldwrt, ldok, kdlev, cdcomp ) 
    4850      !!--------------------------------------------------------------------- 
    4951      !!                   ***  SUBROUTINE  iom_open  *** 
     
    5557      LOGICAL                , INTENT(in   )           ::   ldwrt       ! read or write the file? 
    5658      LOGICAL                , INTENT(in   )           ::   ldok        ! check the existence  
    57       INTEGER, DIMENSION(2,5), INTENT(in   ), OPTIONAL ::   kdompar     ! domain parameters:  
    58       INTEGER                , INTENT(in   ), OPTIONAL ::   kdlev       ! size of the third dimension 
     59      INTEGER                , INTENT(in   ), OPTIONAL ::   kdlev       ! size of the ice/abl third dimension 
     60      CHARACTER(len=3)       , INTENT(in   ), OPTIONAL ::   cdcomp      ! name of component calling iom_nf90_open 
    5961 
    6062      CHARACTER(LEN=256) ::   clinfo           ! info character 
    6163      CHARACTER(LEN=256) ::   cltmp            ! temporary character 
     64      CHARACTER(LEN=12 ) ::   clfmt            ! writing format 
     65      CHARACTER(LEN=3  ) ::   clcomp           ! name of component calling iom_nf90_open 
     66      INTEGER            ::   idg              ! number of digits 
    6267      INTEGER            ::   iln              ! lengths of character 
    6368      INTEGER            ::   istop            ! temporary storage of nstop 
     
    6974      INTEGER            ::   ihdf5            ! local variable for retrieval of value for NF90_HDF5 
    7075      LOGICAL            ::   llclobber        ! local definition of ln_clobber 
    71       INTEGER            ::   ilevels           ! vertical levels 
    7276      !--------------------------------------------------------------------- 
    7377      ! 
     
    7680      ! 
    7781      !                 !number of vertical levels 
    78       IF( PRESENT(kdlev) ) THEN   ;   ilevels = kdlev    ! use input value (useful for sea-ice) 
    79       ELSE                        ;   ilevels = jpk      ! by default jpk 
     82      IF( PRESENT(cdcomp) )   THEN 
     83         IF( .NOT. PRESENT(kdlev) ) CALL ctl_stop( 'iom_nf90_open: cdcomp and kdlev must both be present' ) 
     84         clcomp = cdcomp    ! use input value 
     85      ELSE 
     86         clcomp = 'OCE'     ! by default  
    8087      ENDIF 
    8188      ! 
     
    104111         IF( ldwrt ) THEN              !* the file should be open in write mode so we create it... 
    105112            IF( jpnij > 1 ) THEN 
    106                WRITE(cltmp,'(a,a,i4.4,a)') cdname(1:iln-1), '_', narea-1, '.nc' 
     113               idg = MAX( INT(LOG10(REAL(MAX(1,jpnij-1),wp))) + 1, 4 )          ! how many digits to we need to write? min=4, max=9 
     114               WRITE(clfmt, "('(a,a,i', i1, '.', i1, ',a)')") idg, idg          ! '(a,a,ix.x,a)' 
     115               WRITE(cltmp,clfmt) cdname(1:iln-1), '_', narea-1, '.nc' 
    107116               cdname = TRIM(cltmp) 
    108117            ENDIF 
     
    124133            CALL iom_nf90_check(NF90_SET_FILL( if90id, NF90_NOFILL,                   idmy ), clinfo) 
    125134            ! define dimensions 
    126             CALL iom_nf90_check(NF90_DEF_DIM( if90id,            'x',   kdompar(1,1), idmy ), clinfo) 
    127             CALL iom_nf90_check(NF90_DEF_DIM( if90id,            'y',   kdompar(2,1), idmy ), clinfo) 
    128             CALL iom_nf90_check(NF90_DEF_DIM( if90id,      'nav_lev',            jpk, idmy ), clinfo) 
    129             CALL iom_nf90_check(NF90_DEF_DIM( if90id, 'time_counter', NF90_UNLIMITED, idmy ), clinfo) 
    130             IF( PRESENT(kdlev) )   & 
    131                CALL iom_nf90_check(NF90_DEF_DIM( if90id,    'numcat',          kdlev, idmy ), clinfo) 
     135                               CALL iom_nf90_check(NF90_DEF_DIM( if90id,            'x',  Ni_0, idmy ), clinfo) 
     136                               CALL iom_nf90_check(NF90_DEF_DIM( if90id,            'y',  Nj_0, idmy ), clinfo) 
     137            SELECT CASE (clcomp) 
     138            CASE ('OCE')   ;   CALL iom_nf90_check(NF90_DEF_DIM( if90id,      'nav_lev',   jpk, idmy ), clinfo) 
     139            CASE ('ICE')   ;   CALL iom_nf90_check(NF90_DEF_DIM( if90id,       'numcat', kdlev, idmy ), clinfo) 
     140            CASE ('ABL')   ;   CALL iom_nf90_check(NF90_DEF_DIM( if90id,      'nav_lev', kdlev, idmy ), clinfo) 
     141            CASE ('SED')   ;   CALL iom_nf90_check(NF90_DEF_DIM( if90id,       'numsed', kdlev, idmy ), clinfo) 
     142            CASE DEFAULT   ;   CALL ctl_stop( 'iom_nf90_open unknown component type' ) 
     143            END SELECT 
     144                               CALL iom_nf90_check(NF90_DEF_DIM( if90id, 'time_counter', NF90_UNLIMITED, idmy ), clinfo) 
    132145            ! global attributes 
    133             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_number_total'   , jpnij              ), clinfo) 
    134             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_number'         , narea-1            ), clinfo) 
    135             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_dimensions_ids' , (/1     , 2     /) ), clinfo) 
    136             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_size_global'    , (/jpiglo, jpjglo/) ), clinfo) 
    137             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_size_local'     , kdompar(:,1)      ), clinfo) 
    138             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_position_first' , kdompar(:,2)      ), clinfo) 
    139             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_position_last'  , kdompar(:,3)      ), clinfo) 
    140             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_halo_size_start', kdompar(:,4)      ), clinfo) 
    141             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_halo_size_end'  , kdompar(:,5)      ), clinfo) 
    142             CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_type'           , 'BOX'              ), clinfo) 
     146            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_number_total'   , jpnij                        ), clinfo) 
     147            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_number'         , narea-1                      ), clinfo) 
     148            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_dimensions_ids' , (/ 1        , 2           /) ), clinfo) 
     149            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_size_global'    , (/ Ni0glo    , Nj0glo     /) ), clinfo) 
     150            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_size_local'     , (/ Ni_0      , Nj_0       /) ), clinfo) 
     151            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_position_first' , (/ mig0(Nis0), mjg0(Njs0) /) ), clinfo) 
     152            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_position_last'  , (/ mig0(Nie0), mjg0(Nje0) /) ), clinfo) 
     153            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_halo_size_start', (/ 0         , 0          /) ), clinfo) 
     154            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_halo_size_end'  , (/ 0         , 0          /) ), clinfo) 
     155            CALL iom_nf90_check(NF90_PUT_ATT( if90id, NF90_GLOBAL, 'DOMAIN_type'           , 'BOX'                        ), clinfo) 
    143156         ELSE                          !* the file should be open for read mode so it must exist... 
    144157            CALL ctl_stop( TRIM(clinfo), ' should be impossible case...' ) 
     
    155168         ENDDO 
    156169         iom_file(kiomid)%name   = TRIM(cdname) 
     170         iom_file(kiomid)%comp   = clcomp 
    157171         iom_file(kiomid)%nfid   = if90id 
    158172         iom_file(kiomid)%nvars  = 0 
    159173         iom_file(kiomid)%irec   = -1   ! useless for NetCDF files, used to know if the file is in define mode  
    160          iom_file(kiomid)%nlev   = ilevels 
    161174         CALL iom_nf90_check(NF90_Inquire(if90id, unlimitedDimId = iom_file(kiomid)%iduld), clinfo) 
    162175         IF( iom_file(kiomid)%iduld .GE. 0 ) THEN 
     
    187200 
    188201 
    189    FUNCTION iom_nf90_varid ( kiomid, cdvar, kiv, kdimsz, kndims 
     202   FUNCTION iom_nf90_varid ( kiomid, cdvar, kiv, kdimsz, kndims, lduld 
    190203      !!----------------------------------------------------------------------- 
    191204      !!                  ***  FUNCTION  iom_varid  *** 
     
    196209      CHARACTER(len=*)     , INTENT(in   )           ::   cdvar    ! name of the variable 
    197210      INTEGER              , INTENT(in   )           ::   kiv   !  
    198       INTEGER, DIMENSION(:), INTENT(  out), OPTIONAL ::   kdimsz   ! size of the dimensions 
    199       INTEGER,               INTENT(  out), OPTIONAL ::   kndims   ! size of the dimensions 
     211      INTEGER, DIMENSION(:), INTENT(  out), OPTIONAL ::   kdimsz   ! size of each dimension 
     212      INTEGER              , INTENT(  out), OPTIONAL ::   kndims   ! number of dimensions 
     213      LOGICAL              , INTENT(  out), OPTIONAL ::   lduld    ! true if the last dimension is unlimited (time) 
    200214      ! 
    201215      INTEGER                        ::   iom_nf90_varid   ! iom variable Id 
     
    251265         ENDIF 
    252266         IF( PRESENT(kndims) )  kndims = iom_file(kiomid)%ndims(kiv) 
     267         IF( PRESENT( lduld) )  lduld  = iom_file(kiomid)%luld(kiv) 
    253268      ELSE   
    254269         iom_nf90_varid = -1   !   variable not found, return error code: -1 
     
    261276   !!---------------------------------------------------------------------- 
    262277 
    263    SUBROUTINE iom_nf90_g0d( kiomid, kvid, pvar, kstart ) 
     278   SUBROUTINE iom_nf90_g0d_sp( kiomid, kvid, pvar, kstart ) 
    264279      !!----------------------------------------------------------------------- 
    265280      !!                  ***  ROUTINE  iom_nf90_g0d  *** 
     
    269284      INTEGER ,               INTENT(in   )            ::   kiomid   ! Identifier of the file 
    270285      INTEGER ,               INTENT(in   )            ::   kvid     ! variable id 
    271       REAL(wp),               INTENT(  out)            ::   pvar     ! read field 
     286      REAL(sp),               INTENT(  out)            ::   pvar     ! read field 
    272287      INTEGER , DIMENSION(1), INTENT(in   ), OPTIONAL  ::   kstart   ! start position of the reading in each axis 
    273288      ! 
     
    276291      clinfo = 'iom_nf90_g0d , file: '//TRIM(iom_file(kiomid)%name)//', var: '//TRIM(iom_file(kiomid)%cn_var(kvid)) 
    277292      CALL iom_nf90_check(NF90_GET_VAR(iom_file(kiomid)%nfid, iom_file(kiomid)%nvid(kvid), pvar, start = kstart), clinfo ) 
    278    END SUBROUTINE iom_nf90_g0d 
    279  
    280  
    281    SUBROUTINE iom_nf90_g123d( kiomid, kvid, knbdim, kstart, kcount, kx1, kx2, ky1, ky2,   & 
     293   END SUBROUTINE iom_nf90_g0d_sp 
     294 
     295   SUBROUTINE iom_nf90_g0d_dp( kiomid, kvid, pvar, kstart ) 
     296      !!----------------------------------------------------------------------- 
     297      !!                  ***  ROUTINE  iom_nf90_g0d  *** 
     298      !! 
     299      !! ** Purpose : read a scalar with NF90 
     300      !!----------------------------------------------------------------------- 
     301      INTEGER ,               INTENT(in   )            ::   kiomid   ! Identifier of the file 
     302      INTEGER ,               INTENT(in   )            ::   kvid     ! variable id 
     303      REAL(dp),               INTENT(  out)            ::   pvar     ! read field 
     304      INTEGER , DIMENSION(1), INTENT(in   ), OPTIONAL  ::   kstart   ! start position of the reading in each axis 
     305      ! 
     306      CHARACTER(LEN=100)      ::   clinfo   ! info character 
     307      !--------------------------------------------------------------------- 
     308      clinfo = 'iom_nf90_g0d , file: '//TRIM(iom_file(kiomid)%name)//', var: '//TRIM(iom_file(kiomid)%cn_var(kvid)) 
     309      CALL iom_nf90_check(NF90_GET_VAR(iom_file(kiomid)%nfid, iom_file(kiomid)%nvid(kvid), pvar, start = kstart), clinfo ) 
     310   END SUBROUTINE iom_nf90_g0d_dp 
     311 
     312   SUBROUTINE iom_nf90_g123d_dp( kiomid, kvid, knbdim, kstart, kcount, kx1, kx2, ky1, ky2,   & 
    282313         &                    pv_r1d, pv_r2d, pv_r3d ) 
    283314      !!----------------------------------------------------------------------- 
     
    294325      INTEGER , DIMENSION(:)     , INTENT(in   )           ::   kcount    ! number of points to be read in each axis 
    295326      INTEGER ,                    INTENT(in   )           ::   kx1, kx2, ky1, ky2   ! subdomain indexes 
    296       REAL(wp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d    ! read field (1D case) 
    297       REAL(wp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d    ! read field (2D case) 
    298       REAL(wp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d    ! read field (3D case) 
     327      REAL(dp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d    ! read field (1D case) 
     328      REAL(dp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d    ! read field (2D case) 
     329      REAL(dp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d    ! read field (3D case) 
    299330      ! 
    300331      CHARACTER(LEN=100) ::   clinfo               ! info character 
     
    317348      ENDIF 
    318349      ! 
    319    END SUBROUTINE iom_nf90_g123d 
     350   END SUBROUTINE iom_nf90_g123d_dp 
     351 
    320352 
    321353 
     
    491523   END SUBROUTINE iom_nf90_putatt 
    492524 
    493  
    494    SUBROUTINE iom_nf90_rp0123d( kt, kwrite, kiomid, cdvar , kvid  , ktype,   & 
     525   SUBROUTINE iom_nf90_rp0123d_dp( kt, kwrite, kiomid, cdvar , kvid  , ktype,   & 
    495526         &                                  pv_r0d, pv_r1d, pv_r2d, pv_r3d ) 
    496527      !!-------------------------------------------------------------------- 
     
    505536      INTEGER                     , INTENT(in)           ::   kvid     ! variable id 
    506537      INTEGER                     , INTENT(in), OPTIONAL ::   ktype    ! variable type (default R8) 
    507       REAL(wp)                    , INTENT(in), OPTIONAL ::   pv_r0d   ! written Od field 
    508       REAL(wp), DIMENSION(      :), INTENT(in), OPTIONAL ::   pv_r1d   ! written 1d field 
    509       REAL(wp), DIMENSION(:, :   ), INTENT(in), OPTIONAL ::   pv_r2d   ! written 2d field 
    510       REAL(wp), DIMENSION(:, :, :), INTENT(in), OPTIONAL ::   pv_r3d   ! written 3d field 
     538      REAL(dp)                    , INTENT(in), OPTIONAL ::   pv_r0d   ! written Od field 
     539      REAL(dp), DIMENSION(      :), INTENT(in), OPTIONAL ::   pv_r1d   ! written 1d field 
     540      REAL(dp), DIMENSION(:, :   ), INTENT(in), OPTIONAL ::   pv_r2d   ! written 2d field 
     541      REAL(dp), DIMENSION(:, :, :), INTENT(in), OPTIONAL ::   pv_r3d   ! written 3d field 
    511542      ! 
    512543      INTEGER               :: idims                ! number of dimension 
     
    517548      INTEGER, DIMENSION(4) :: idimid               ! dimensions id 
    518549      CHARACTER(LEN=256)    :: clinfo               ! info character 
    519       CHARACTER(LEN= 12), DIMENSION(5) :: cltmp     ! temporary character 
    520550      INTEGER               :: if90id               ! nf90 file identifier 
    521       INTEGER               :: idmy                 ! dummy variable 
    522551      INTEGER               :: itype                ! variable type 
    523552      INTEGER, DIMENSION(4) :: ichunksz             ! NetCDF4 chunk sizes. Will be computed using 
     
    528557      !                                             ! when appropriate (currently chunking is applied to 4d fields only) 
    529558      INTEGER               :: idlv                 ! local variable 
    530       INTEGER               :: idim3                ! id of the third dimension 
    531       ! 
    532     !  INTEGER ::   nldi_save, nlei_save    !:patch before we remove periodicity and close boundaries in output files 
    533     !  INTEGER ::   nldj_save, nlej_save    !: 
    534559      !--------------------------------------------------------------------- 
    535560      ! 
    536561      clinfo = '          iom_nf90_rp0123d, file: '//TRIM(iom_file(kiomid)%name)//', var: '//TRIM(cdvar) 
    537562      if90id = iom_file(kiomid)%nfid 
    538       ! 
    539       ! use patch to force the writing off periodicity and close boundaries 
    540       ! without this, issue in some model decomposition 
    541       ! seb: patch before we remove periodicity and close boundaries in output files 
    542     !  nldi_save = nldi   ;   nlei_save = nlei 
    543     !  nldj_save = nldj   ;   nlej_save = nlej 
    544     !  IF( nimpp           ==      1 ) nldi = 1 
    545     !  IF( nimpp + jpi - 1 == jpiglo ) nlei = jpi 
    546     !  IF( njmpp           ==      1 ) nldj = 1 
    547     !  IF( njmpp + jpj - 1 == jpjglo ) nlej = jpj 
    548563      ! 
    549564      ! define dimension variables if it is not already done 
     
    555570         ENDIF 
    556571         ! define the dimension variables if it is not already done 
    557          ! Warning: we must use the same character length in an array constructor (at least for gcc compiler) 
    558          cltmp = (/ 'nav_lon     ', 'nav_lat     ', 'nav_lev     ', 'time_counter', 'numcat      ' /)    
    559          CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(cltmp(1)), NF90_FLOAT , (/ 1, 2 /), iom_file(kiomid)%nvid(1) ), clinfo) 
    560          CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(cltmp(2)), NF90_FLOAT , (/ 1, 2 /), iom_file(kiomid)%nvid(2) ), clinfo) 
    561          CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(cltmp(3)), NF90_FLOAT , (/ 3    /), iom_file(kiomid)%nvid(3) ), clinfo) 
    562          CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(cltmp(4)), NF90_DOUBLE, (/ 4    /), iom_file(kiomid)%nvid(4) ), clinfo) 
     572         DO jd = 1, 2 
     573            CALL iom_nf90_check(NF90_INQUIRE_DIMENSION(if90id,jd,iom_file(kiomid)%cn_var(jd),iom_file(kiomid)%dimsz(jd,jd)),clinfo) 
     574            CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(iom_file(kiomid)%cn_var(jd)), NF90_FLOAT , (/ 1, 2 /),   & 
     575               &                              iom_file(kiomid)%nvid(jd) ), clinfo) 
     576         END DO 
     577         iom_file(kiomid)%dimsz(2,1) = iom_file(kiomid)%dimsz(2,2)   ! second dim of first  variable 
     578         iom_file(kiomid)%dimsz(1,2) = iom_file(kiomid)%dimsz(1,1)   ! first  dim of second variable 
     579         DO jd = 3, 4 
     580            CALL iom_nf90_check(NF90_INQUIRE_DIMENSION(if90id,jd,iom_file(kiomid)%cn_var(jd),iom_file(kiomid)%dimsz(1,jd)), clinfo) 
     581            CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(iom_file(kiomid)%cn_var(jd)), NF90_FLOAT , (/ jd   /),   & 
     582               &                              iom_file(kiomid)%nvid(jd) ), clinfo) 
     583         END DO 
    563584         ! update informations structure related the dimension variable we just added... 
    564585         iom_file(kiomid)%nvars       = 4 
    565586         iom_file(kiomid)%luld(1:4)   = (/ .FALSE., .FALSE., .FALSE., .TRUE. /) 
    566          iom_file(kiomid)%cn_var(1:4) = cltmp(1:4) 
    567587         iom_file(kiomid)%ndims(1:4)  = (/ 2, 2, 1, 1 /) 
    568          IF( NF90_INQ_DIMID( if90id, 'numcat', idmy ) == nf90_noerr ) THEN   ! add a 5th variable corresponding to the 5th dimension 
    569             CALL iom_nf90_check(NF90_DEF_VAR( if90id, TRIM(cltmp(5)), NF90_FLOAT , (/ 5 /), iom_file(kiomid)%nvid(5) ), clinfo) 
    570             iom_file(kiomid)%nvars     = 5 
    571             iom_file(kiomid)%luld(5)   = .FALSE. 
    572             iom_file(kiomid)%cn_var(5) = cltmp(5) 
    573             iom_file(kiomid)%ndims(5)  = 1 
    574          ENDIF 
    575          ! trick: defined to 0 to say that dimension variables are defined but not yet written 
    576          iom_file(kiomid)%dimsz(1, 1)  = 0    
    577588         IF(lwp) WRITE(numout,*) TRIM(clinfo)//' define dimension variables done' 
    578589      ENDIF 
     
    595606         IF(     PRESENT(pv_r0d) ) THEN   ;   idims = 0 
    596607         ELSEIF( PRESENT(pv_r1d) ) THEN 
    597             IF( SIZE(pv_r1d,1) == jpk ) THEN   ;   idim3 = 3 
    598             ELSE                               ;   idim3 = 5 
    599             ENDIF 
    600                                               idims = 2   ;   idimid(1:idims) = (/idim3,4/) 
    601          ELSEIF( PRESENT(pv_r2d) ) THEN   ;   idims = 3   ;   idimid(1:idims) = (/1,2  ,4/) 
     608                                              idims = 2   ;   idimid(1:idims) = (/3,4/) 
     609         ELSEIF( PRESENT(pv_r2d) ) THEN   ;   idims = 3   ;   idimid(1:idims) = (/1,2,4/) 
    602610         ELSEIF( PRESENT(pv_r3d) ) THEN 
    603             IF( SIZE(pv_r3d,3) == jpk ) THEN   ;   idim3 = 3 
    604             ELSE                               ;   idim3 = 5 
    605             ENDIF 
    606                                               idims = 4   ;   idimid(1:idims) = (/1,2,idim3,4/) 
     611                                              idims = 4   ;   idimid(1:idims) = (/1,2,3,4/) 
    607612         ENDIF 
    608613         IF( PRESENT(ktype) ) THEN   ! variable external type 
     
    666671         IF( PRESENT(pv_r2d) .OR. PRESENT(pv_r3d) ) THEN 
    667672            idimsz(1:2) = iom_file(kiomid)%dimsz(1:2,idvar) 
    668             IF(     idimsz(1) == (nlei - nldi + 1) .AND. idimsz(2) == (nlej - nldj + 1) ) THEN 
    669                ix1 = nldi   ;   ix2 = nlei   ;   iy1 = nldj   ;   iy2 = nlej 
    670             ELSEIF( idimsz(1) == nlci              .AND. idimsz(2) == nlcj              ) THEN 
    671                ix1 = 1      ;   ix2 = nlci   ;   iy1 = 1      ;   iy2 = nlcj 
    672             ELSEIF( idimsz(1) == jpi               .AND. idimsz(2) == jpj               ) THEN 
     673            IF(     idimsz(1) == Ni_0 .AND. idimsz(2) == Nj_0 ) THEN 
     674               ix1 = Nis0   ;   ix2 = Nie0   ;   iy1 = Njs0   ;   iy2 = Nje0 
     675            ELSEIF( idimsz(1) == jpi  .AND. idimsz(2) == jpj  ) THEN 
     676               ix1 = 1      ;   ix2 = jpi    ;   iy1 = 1      ;   iy2 = jpj 
     677            ELSEIF( idimsz(1) == jpi  .AND. idimsz(2) == jpj  ) THEN 
    673678               ix1 = 1      ;   ix2 = jpi    ;   iy1 = 1      ;   iy2 = jpj 
    674679            ELSE  
     
    679684            ! ============= 
    680685            ! trick: is defined to 0 => dimension variable are defined but not yet written 
    681             IF( iom_file(kiomid)%dimsz(1, 1) == 0 ) THEN 
    682                CALL iom_nf90_check( NF90_INQ_VARID( if90id, 'nav_lon'     , idmy )         , clinfo ) 
    683                CALL iom_nf90_check( NF90_PUT_VAR  ( if90id, idmy, glamt(ix1:ix2, iy1:iy2) ), clinfo ) 
    684                CALL iom_nf90_check( NF90_INQ_VARID( if90id, 'nav_lat'     , idmy )         , clinfo ) 
    685                CALL iom_nf90_check( NF90_PUT_VAR  ( if90id, idmy, gphit(ix1:ix2, iy1:iy2) ), clinfo ) 
    686                CALL iom_nf90_check( NF90_INQ_VARID( if90id, 'nav_lev'     , idmy ), clinfo ) 
    687                CALL iom_nf90_check( NF90_PUT_VAR  ( if90id, idmy, gdept_1d       ), clinfo ) 
    688                IF( NF90_INQ_VARID( if90id, 'numcat', idmy ) == nf90_noerr ) THEN 
    689                   CALL iom_nf90_check( NF90_PUT_VAR  ( if90id, idmy, (/ (idlv, idlv = 1,iom_file(kiomid)%nlev) /)), clinfo ) 
    690                ENDIF 
    691                ! +++ WRONG VALUE: to be improved but not really useful... 
    692                CALL iom_nf90_check( NF90_INQ_VARID( if90id, 'time_counter', idmy ), clinfo ) 
    693                CALL iom_nf90_check( NF90_PUT_VAR( if90id, idmy, kt                      ), clinfo )    
    694                ! update the values of the variables dimensions size 
    695                CALL iom_nf90_check( NF90_INQUIRE_DIMENSION( if90id, 1, len = iom_file(kiomid)%dimsz(1,1) ), clinfo ) 
    696                CALL iom_nf90_check( NF90_INQUIRE_DIMENSION( if90id, 2, len = iom_file(kiomid)%dimsz(2,1) ), clinfo ) 
    697                iom_file(kiomid)%dimsz(1:2, 2) = iom_file(kiomid)%dimsz(1:2, 1) 
    698                CALL iom_nf90_check( NF90_INQUIRE_DIMENSION( if90id, 3, len = iom_file(kiomid)%dimsz(1,3) ), clinfo ) 
    699                iom_file(kiomid)%dimsz(1  , 4) = 1   ! unlimited dimension 
     686            IF( iom_file(kiomid)%dimsz(1, 4) == 0 ) THEN   ! time_counter = 0 
     687               CALL iom_nf90_check(    NF90_PUT_VAR( if90id, 1,                            glamt(ix1:ix2, iy1:iy2) ), clinfo ) 
     688               CALL iom_nf90_check(    NF90_PUT_VAR( if90id, 2,                            gphit(ix1:ix2, iy1:iy2) ), clinfo ) 
     689               SELECT CASE (iom_file(kiomid)%comp) 
     690               CASE ('OCE')   
     691                  CALL iom_nf90_check( NF90_PUT_VAR( if90id, 3,                                           gdept_1d ), clinfo ) 
     692            !   CASE ('ABL') 
     693            !      CALL iom_nf90_check( NF90_PUT_VAR( if90id, 3,                                            ght_abl ), clinfo ) 
     694               CASE DEFAULT 
     695                  CALL iom_nf90_check( NF90_PUT_VAR( if90id, 3, (/ (idlv, idlv = 1,iom_file(kiomid)%dimsz(1,3)) /) ), clinfo ) 
     696               END SELECT 
     697               ! "wrong" value: to be improved but not really useful... 
     698               CALL iom_nf90_check(   NF90_PUT_VAR( if90id, 4,                                                  kt ), clinfo )    
     699               ! update the size of the variable corresponding to the unlimited dimension 
     700               iom_file(kiomid)%dimsz(1, 4) = 1   ! so we don't enter this IF case any more... 
    700701               IF(lwp) WRITE(numout,*) TRIM(clinfo)//' write dimension variables done' 
    701702            ENDIF 
     
    718719         IF(lwp) WRITE(numout,*) TRIM(clinfo)//' written ok' 
    719720      ENDIF 
    720       ! 
    721   !    nldi = nldi_save   ;   nlei = nlei_save 
    722   !    nldj = nldj_save   ;   nlej = nlej_save 
    723721      !      
    724    END SUBROUTINE iom_nf90_rp0123d 
     722   END SUBROUTINE iom_nf90_rp0123d_dp 
    725723 
    726724 
  • utils/tools/DOMAINcfg/src/lbc_lnk_multi_generic.h90

    r12414 r14623  
    1 #if defined DIM_2d 
    2 #   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j) 
    3 #   define PTR_TYPE              TYPE(PTR_2D) 
    4 #   define PTR_ptab              pt2d 
     1#if defined SINGLE_PRECISION 
     2#   if defined DIM_2d 
     3#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j) 
     4#      define PTR_TYPE              TYPE(PTR_2D_sp) 
     5#      define PTR_ptab              pt2d 
     6#   endif 
     7#   if defined DIM_3d 
     8#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k) 
     9#      define PTR_TYPE              TYPE(PTR_3D_sp) 
     10#      define PTR_ptab              pt3d 
     11#   endif 
     12#   if defined DIM_4d 
     13#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k,l) 
     14#      define PTR_TYPE              TYPE(PTR_4D_sp) 
     15#      define PTR_ptab              pt4d 
     16#   endif 
     17#   define PRECISION sp 
     18#else 
     19#   if defined DIM_2d 
     20#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j) 
     21#      define PTR_TYPE              TYPE(PTR_2D_dp) 
     22#      define PTR_ptab              pt2d 
     23#   endif 
     24#   if defined DIM_3d 
     25#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k) 
     26#      define PTR_TYPE              TYPE(PTR_3D_dp) 
     27#      define PTR_ptab              pt3d 
     28#   endif 
     29#   if defined DIM_4d 
     30#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k,l) 
     31#      define PTR_TYPE              TYPE(PTR_4D_dp) 
     32#      define PTR_ptab              pt4d 
     33#   endif 
     34#   define PRECISION dp 
    535#endif 
    6 #if defined DIM_3d 
    7 #   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j,k) 
    8 #   define PTR_TYPE              TYPE(PTR_3D) 
    9 #   define PTR_ptab              pt3d 
    10 #endif 
    11 #if defined DIM_4d 
    12 #   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j,k,l) 
    13 #   define PTR_TYPE              TYPE(PTR_4D) 
    14 #   define PTR_ptab              pt4d 
    15 #endif 
    16    SUBROUTINE ROUTINE_MULTI( cdname                                                    & 
    17       &                    , pt1, cdna1, psgn1, pt2, cdna2, psgn2, pt3, cdna3, psgn3   & 
    18       &                    , pt4, cdna4, psgn4, pt5, cdna5, psgn5, pt6, cdna6, psgn6   & 
    19       &                    , pt7, cdna7, psgn7, pt8, cdna8, psgn8, pt9, cdna9, psgn9, cd_mpp, pval) 
     36 
     37   SUBROUTINE ROUTINE_MULTI( cdname                                                                             & 
     38      &                    , pt1, cdna1, psgn1, pt2 , cdna2 , psgn2 , pt3 , cdna3 , psgn3 , pt4, cdna4, psgn4   & 
     39      &                    , pt5, cdna5, psgn5, pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8, cdna8, psgn8   & 
     40      &                    , pt9, cdna9, psgn9, pt10, cdna10, psgn10, pt11, cdna11, psgn11                      & 
     41      &                    , kfillmode, pfillval, lsend, lrecv ) 
    2042      !!--------------------------------------------------------------------- 
    21       CHARACTER(len=*)   ,                   INTENT(in   ) ::   cdname  ! name of the calling subroutine 
    22       ARRAY_TYPE(:,:,:,:)          , TARGET, INTENT(inout) ::   pt1     ! arrays on which the lbc is applied 
    23       ARRAY_TYPE(:,:,:,:), OPTIONAL, TARGET, INTENT(inout) ::   pt2  ,  pt3  , pt4  , pt5  , pt6  , pt7  , pt8  , pt9 
    24       CHARACTER(len=1)                     , INTENT(in   ) ::   cdna1   ! nature of pt2D. array grid-points 
    25       CHARACTER(len=1)   , OPTIONAL        , INTENT(in   ) ::   cdna2,  cdna3, cdna4, cdna5, cdna6, cdna7, cdna8, cdna9 
    26       REAL(wp)                             , INTENT(in   ) ::   psgn1   ! sign used across the north fold 
    27       REAL(wp)           , OPTIONAL        , INTENT(in   ) ::   psgn2,  psgn3, psgn4, psgn5, psgn6, psgn7, psgn8, psgn9    
    28       CHARACTER(len=3)   , OPTIONAL        , INTENT(in   ) ::   cd_mpp  ! fill the overlap area only 
    29       REAL(wp)           , OPTIONAL        , INTENT(in   ) ::   pval    ! background value (used at closed boundaries) 
     43      CHARACTER(len=*)   ,                   INTENT(in   ) :: cdname  ! name of the calling subroutine 
     44      ARRAY_TYPE(:,:,:,:)          , TARGET, INTENT(inout) :: pt1     ! arrays on which the lbc is applied 
     45      ARRAY_TYPE(:,:,:,:), OPTIONAL, TARGET, INTENT(inout) :: pt2  , pt3  , pt4  , pt5  , pt6  , pt7  , pt8  , pt9  , pt10  , pt11 
     46      CHARACTER(len=1)                     , INTENT(in   ) :: cdna1   ! nature of pt2D. array grid-points 
     47      CHARACTER(len=1)   , OPTIONAL        , INTENT(in   ) :: cdna2, cdna3, cdna4, cdna5, cdna6, cdna7, cdna8, cdna9, cdna10, cdna11 
     48      REAL(wp)                             , INTENT(in   ) :: psgn1   ! sign used across the north fold 
     49      REAL(wp)           , OPTIONAL        , INTENT(in   ) :: psgn2, psgn3, psgn4, psgn5, psgn6, psgn7, psgn8, psgn9, psgn10, psgn11 
     50      INTEGER            , OPTIONAL        , INTENT(in   ) :: kfillmode   ! filling method for halo over land (default = constant) 
     51      REAL(wp)           , OPTIONAL        , INTENT(in   ) :: pfillval    ! background value (used at closed boundaries) 
     52      LOGICAL, DIMENSION(4), OPTIONAL      , INTENT(in   ) :: lsend, lrecv   ! indicate how communications are to be carried out 
    3053      !! 
    31       INTEGER                         ::   kfld        ! number of elements that will be attributed 
    32       PTR_TYPE         , DIMENSION(9) ::   ptab_ptr    ! pointer array 
    33       CHARACTER(len=1) , DIMENSION(9) ::   cdna_ptr    ! nature of ptab_ptr grid-points 
    34       REAL(wp)         , DIMENSION(9) ::   psgn_ptr    ! sign used across the north fold boundary 
     54      INTEGER                          ::   kfld        ! number of elements that will be attributed 
     55      PTR_TYPE         , DIMENSION(11) ::   ptab_ptr    ! pointer array 
     56      CHARACTER(len=1) , DIMENSION(11) ::   cdna_ptr    ! nature of ptab_ptr grid-points 
     57      REAL(wp)         , DIMENSION(11) ::   psgn_ptr    ! sign used across the north fold boundary 
    3558      !!--------------------------------------------------------------------- 
    3659      ! 
     
    4164      ! 
    4265      !                 ! Look if more arrays are added 
    43       IF( PRESENT(psgn2) )   CALL ROUTINE_LOAD( pt2, cdna2, psgn2, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    44       IF( PRESENT(psgn3) )   CALL ROUTINE_LOAD( pt3, cdna3, psgn3, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    45       IF( PRESENT(psgn4) )   CALL ROUTINE_LOAD( pt4, cdna4, psgn4, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    46       IF( PRESENT(psgn5) )   CALL ROUTINE_LOAD( pt5, cdna5, psgn5, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    47       IF( PRESENT(psgn6) )   CALL ROUTINE_LOAD( pt6, cdna6, psgn6, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    48       IF( PRESENT(psgn7) )   CALL ROUTINE_LOAD( pt7, cdna7, psgn7, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    49       IF( PRESENT(psgn8) )   CALL ROUTINE_LOAD( pt8, cdna8, psgn8, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    50       IF( PRESENT(psgn9) )   CALL ROUTINE_LOAD( pt9, cdna9, psgn9, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     66      IF( PRESENT(psgn2 ) )   CALL ROUTINE_LOAD( pt2 , cdna2 , psgn2 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     67      IF( PRESENT(psgn3 ) )   CALL ROUTINE_LOAD( pt3 , cdna3 , psgn3 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     68      IF( PRESENT(psgn4 ) )   CALL ROUTINE_LOAD( pt4 , cdna4 , psgn4 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     69      IF( PRESENT(psgn5 ) )   CALL ROUTINE_LOAD( pt5 , cdna5 , psgn5 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     70      IF( PRESENT(psgn6 ) )   CALL ROUTINE_LOAD( pt6 , cdna6 , psgn6 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     71      IF( PRESENT(psgn7 ) )   CALL ROUTINE_LOAD( pt7 , cdna7 , psgn7 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     72      IF( PRESENT(psgn8 ) )   CALL ROUTINE_LOAD( pt8 , cdna8 , psgn8 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     73      IF( PRESENT(psgn9 ) )   CALL ROUTINE_LOAD( pt9 , cdna9 , psgn9 , ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     74      IF( PRESENT(psgn10) )   CALL ROUTINE_LOAD( pt10, cdna10, psgn10, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
     75      IF( PRESENT(psgn11) )   CALL ROUTINE_LOAD( pt11, cdna11, psgn11, ptab_ptr, cdna_ptr, psgn_ptr, kfld ) 
    5176      ! 
    52       CALL lbc_lnk_ptr( cdname, ptab_ptr, cdna_ptr, psgn_ptr, kfld, cd_mpp, pval ) 
     77      CALL lbc_lnk_ptr    ( cdname,               ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval, lsend, lrecv ) 
    5378      ! 
    5479   END SUBROUTINE ROUTINE_MULTI 
     
    7297      ! 
    7398   END SUBROUTINE ROUTINE_LOAD 
     99 
     100#undef PRECISION 
    74101#undef ARRAY_TYPE 
    75102#undef PTR_TYPE 
  • utils/tools/DOMAINcfg/src/lbc_nfd_ext_generic.h90

    r12414 r14623  
    88#   define L_SIZE(ptab)          1 
    99#endif 
    10 #define ARRAY_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     10#if defined SINGLE_PRECISION 
     11#   define ARRAY_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     12#   define PRECISION sp 
     13#else 
     14#   define ARRAY_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     15#   define PRECISION dp 
     16#endif 
    1117 
    1218   SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kextj ) 
     
    2834      ! 
    2935      SELECT CASE ( jpni ) 
    30       CASE ( 1 )     ;   ipj = nlcj       ! 1 proc only  along the i-direction 
     36      CASE ( 1 )     ;   ipj = jpj        ! 1 proc only  along the i-direction 
    3137      CASE DEFAULT   ;   ipj = 4          ! several proc along the i-direction 
    3238      END SELECT 
     
    149155   END SUBROUTINE ROUTINE_NFD 
    150156 
     157#undef PRECISION 
    151158#undef ARRAY_TYPE 
    152159#undef ARRAY_IN 
  • utils/tools/DOMAINcfg/src/lbc_nfd_generic.h90

    r12414 r14623  
    44#   define F_SIZE(ptab)             kfld 
    55#   if defined DIM_2d 
    6 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D),INTENT(inout)::ptab(f) 
     6#      if defined SINGLE_PRECISION 
     7#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f) 
     8#      else 
     9#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f) 
     10#      endif 
    711#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
     12#      define J_SIZE(ptab)             SIZE(ptab(1)%pt2d,2) 
    813#      define K_SIZE(ptab)             1 
    914#      define L_SIZE(ptab)             1 
    1015#   endif 
    1116#   if defined DIM_3d 
    12 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D),INTENT(inout)::ptab(f) 
     17#      if defined SINGLE_PRECISION 
     18#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f) 
     19#      else 
     20#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f) 
     21#      endif 
    1322#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
     23#      define J_SIZE(ptab)             SIZE(ptab(1)%pt3d,2) 
    1424#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
    1525#      define L_SIZE(ptab)             1 
    1626#   endif 
    1727#   if defined DIM_4d 
    18 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D),INTENT(inout)::ptab(f) 
     28#      if defined SINGLE_PRECISION 
     29#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f) 
     30#      else 
     31#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f) 
     32#      endif 
    1933#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
     34#      define J_SIZE(ptab)             SIZE(ptab(1)%pt4d,2) 
    2035#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
    2136#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4) 
     
    2843#   if defined DIM_2d 
    2944#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j) 
     45#      define J_SIZE(ptab)          SIZE(ptab,2) 
    3046#      define K_SIZE(ptab)          1 
    3147#      define L_SIZE(ptab)          1 
     
    3349#   if defined DIM_3d 
    3450#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k) 
     51#      define J_SIZE(ptab)          SIZE(ptab,2) 
    3552#      define K_SIZE(ptab)          SIZE(ptab,3) 
    3653#      define L_SIZE(ptab)          1 
     
    3855#   if defined DIM_4d 
    3956#      define ARRAY_IN(i,j,k,l,f)   ptab(i,j,k,l) 
     57#      define J_SIZE(ptab)          SIZE(ptab,2) 
    4058#      define K_SIZE(ptab)          SIZE(ptab,3) 
    4159#      define L_SIZE(ptab)          SIZE(ptab,4) 
    4260#   endif 
    43 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     61#   if defined SINGLE_PRECISION 
     62#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     63#   else 
     64#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     65#   endif 
    4466#endif 
     67 
     68#   if defined SINGLE_PRECISION 
     69#      define PRECISION sp 
     70#   else 
     71#      define PRECISION dp 
     72#   endif 
    4573 
    4674#if defined MULTI 
     
    5482      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
    5583      ! 
    56       INTEGER  ::    ji,  jj,  jk,  jl, jh, jf   ! dummy loop indices 
    57       INTEGER  ::   ipi, ipj, ipk, ipl,    ipf   ! dimension of the input array 
    58       INTEGER  ::   ijt, iju, ipjm1 
     84      INTEGER  ::    ji,  jj,  jk,  jl, jf   ! dummy loop indices 
     85      INTEGER  ::        ipj, ipk, ipl, ipf   ! dimension of the input array 
     86      INTEGER  ::   ii1, ii2, ij1, ij2 
    5987      !!---------------------------------------------------------------------- 
    6088      ! 
    61       ipk = K_SIZE(ptab)   ! 3rd dimension 
     89      ipj = J_SIZE(ptab)   ! 2nd dimension 
     90      ipk = K_SIZE(ptab)   ! 3rd    - 
    6291      ipl = L_SIZE(ptab)   ! 4th    - 
    6392      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers) 
    64       ! 
    65       ! 
    66       SELECT CASE ( jpni ) 
    67       CASE ( 1 )     ;   ipj = nlcj       ! 1 proc only  along the i-direction 
    68       CASE DEFAULT   ;   ipj = 4          ! several proc along the i-direction 
    69       END SELECT 
    70       ipjm1 = ipj-1 
    71  
    7293      ! 
    7394      DO jf = 1, ipf                      ! Loop on the number of arrays to be treated 
     
    79100            SELECT CASE ( NAT_IN(jf)  ) 
    80101            CASE ( 'T' , 'W' )                         ! T-, W-point 
    81                DO ji = 2, jpiglo 
    82                   ijt = jpiglo-ji+2 
    83                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-2,:,:,jf) 
    84                END DO 
    85                ARRAY_IN(1,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(3,ipj-2,:,:,jf) 
    86                DO ji = jpiglo/2+1, jpiglo 
    87                   ijt = jpiglo-ji+2 
    88                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipjm1,:,:,jf) 
    89                END DO 
     102               DO jl = 1, ipl; DO jk = 1, ipk 
     103                  ! 
     104                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     105                    DO jj = 1, nn_hls 
     106                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     107                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     108                     ! 
     109                     DO ji = 1, nn_hls            ! first nn_hls points 
     110                        ii1 =                ji          ! ends at: nn_hls 
     111                        ii2 = 2*nn_hls + 2 - ji          ! ends at: 2*nn_hls + 2 - nn_hls = nn_hls + 2 
     112                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     113                     END DO 
     114                     DO ji = 1, 1                 ! point nn_hls+1 
     115                        ii1 = nn_hls + ji 
     116                        ii2 = ii1 
     117                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     118                     END DO 
     119                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+2 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     120                        ii1 = 2 + nn_hls      + ji - 1   ! ends at: 2 + nn_hls + jpiglo - 2*nn_hls - 1 - 1 = jpiglo - nn_hls 
     121                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) + 1 = nn_hls + 2 
     122                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     123                     END DO 
     124                     DO ji = 1, 1                 ! point jpiglo - nn_hls + 1 
     125                        ii1 = jpiglo - nn_hls + ji 
     126                        ii2 =          nn_hls + ji 
     127                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     128                     END DO 
     129                     DO ji = 1, nn_hls-1          ! last nn_hls-1 points 
     130                        ii1 = jpiglo - nn_hls + 1 + ji   ! ends at: jpiglo - nn_hls + 1 + nn_hls - 1 = jpiglo 
     131                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls + 1 = jpiglo - 2*nn_hls + 2 
     132                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     133                     END DO 
     134                  END DO 
     135                  ! 
     136                  ! line number ipj-nn_hls : right half 
     137                    DO jj = 1, 1 
     138                     ij1 = ipj - nn_hls 
     139                     ij2 = ij1   ! same line 
     140                     ! 
     141                     DO ji = 1, Ni0glo/2-1        ! points from jpiglo/2+2 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     142                        ii1 = jpiglo/2 + ji + 1          ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls - 1) + 1 = jpiglo - nn_hls 
     143                        ii2 = jpiglo/2 - ji + 1          ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls - 1) + 1 = nn_hls + 2 
     144                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     145                     END DO 
     146                     DO ji = 1, nn_hls            ! first nn_hls points: redo them just in case (if e-w periodocity already done) 
     147                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hls   
     148                        ii1 =                ji          ! ends at: nn_hls 
     149                        ii2 = 2*nn_hls + 2 - ji          ! ends at: 2*nn_hls + 2 - nn_hls = nn_hls + 2 
     150                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     151                     END DO 
     152                     !                            ! last nn_hls-1 points: have been / will done by e-w periodicity  
     153                  END DO 
     154                  ! 
     155               END DO; END DO 
    90156            CASE ( 'U' )                               ! U-point 
    91                DO ji = 1, jpiglo-1 
    92                   iju = jpiglo-ji+1 
    93                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-2,:,:,jf) 
    94                END DO 
    95                ARRAY_IN(   1  ,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(    2   ,ipj-2,:,:,jf) 
    96                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(jpiglo-1,ipj-2,:,:,jf)  
    97                DO ji = jpiglo/2, jpiglo-1 
    98                   iju = jpiglo-ji+1 
    99                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipjm1,:,:,jf) 
    100                END DO 
     157               DO jl = 1, ipl; DO jk = 1, ipk 
     158                  ! 
     159                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     160                    DO jj = 1, nn_hls 
     161                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     162                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     163                     ! 
     164                     DO ji = 1, nn_hls            ! first nn_hls points 
     165                        ii1 =                ji          ! ends at: nn_hls 
     166                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     167                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     168                     END DO 
     169                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     170                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     171                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     172                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     173                     END DO 
     174                     DO ji = 1, nn_hls            ! last nn_hls points 
     175                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     176                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     177                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     178                     END DO 
     179                  END DO 
     180                  ! 
     181                  ! line number ipj-nn_hls : right half 
     182                    DO jj = 1, 1 
     183                     ij1 = ipj - nn_hls 
     184                     ij2 = ij1   ! same line 
     185                     ! 
     186                     DO ji = 1, Ni0glo/2          ! points from jpiglo/2+1 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     187                        ii1 = jpiglo/2 + ji              ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls) = jpiglo - nn_hls 
     188                        ii2 = jpiglo/2 - ji + 1          ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls) + 1 = nn_hls + 1 
     189                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     190                     END DO 
     191                     DO ji = 1, nn_hls            ! first nn_hls points: redo them just in case (if e-w periodocity already done) 
     192                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hls   
     193                        ii1 =                ji          ! ends at: nn_hls 
     194                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     195                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     196                     END DO 
     197                     !                            ! last nn_hls-1 points: have been / will done by e-w periodicity  
     198                  END DO 
     199                  ! 
     200               END DO; END DO 
    101201            CASE ( 'V' )                               ! V-point 
    102                DO ji = 2, jpiglo 
    103                   ijt = jpiglo-ji+2 
    104                   ARRAY_IN(ji,ipj-1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-2,:,:,jf) 
    105                   ARRAY_IN(ji,ipj  ,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-3,:,:,jf) 
    106                END DO 
    107                ARRAY_IN(1,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(3,ipj-3,:,:,jf)  
     202               DO jl = 1, ipl; DO jk = 1, ipk 
     203                  ! 
     204                  ! last nn_hls+1 lines (from ipj to ipj-nn_hls) : full 
     205                    DO jj = 1, nn_hls+1 
     206                       ij1 = ipj            - jj + 1       ! ends at: ipj - ( nn_hls + 1 ) + 1 = ipj - nn_hls 
     207                     ij2 = ipj - 2*nn_hls + jj - 2       ! ends at: ipj - 2*nn_hls + nn_hls + 1 - 2 = ipj - nn_hls - 1 
     208                     ! 
     209                     DO ji = 1, nn_hls            ! first nn_hls points 
     210                        ii1 =                ji          ! ends at: nn_hls 
     211                        ii2 = 2*nn_hls + 2 - ji          ! ends at: 2*nn_hls + 2 - nn_hls = nn_hls + 2 
     212                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     213                     END DO 
     214                     DO ji = 1, 1                 ! point nn_hls+1 
     215                        ii1 = nn_hls + ji 
     216                        ii2 = ii1 
     217                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     218                     END DO 
     219                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+2 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     220                        ii1 = 2 + nn_hls      + ji - 1   ! ends at: 2 + nn_hls + jpiglo - 2*nn_hls - 1 - 1 = jpiglo - nn_hls 
     221                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) + 1 = nn_hls + 2 
     222                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     223                     END DO 
     224                     DO ji = 1, 1                 ! point jpiglo - nn_hls + 1 
     225                        ii1 = jpiglo - nn_hls + ji 
     226                        ii2 =          nn_hls + ji 
     227                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     228                     END DO 
     229                     DO ji = 1, nn_hls-1          ! last nn_hls-1 points 
     230                        ii1 = jpiglo - nn_hls + 1 + ji   ! ends at: jpiglo - nn_hls + 1 + nn_hls - 1 = jpiglo 
     231                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls + 1 = jpiglo - 2*nn_hls + 2 
     232                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     233                     END DO 
     234                  END DO 
     235                  ! 
     236               END DO; END DO 
    108237            CASE ( 'F' )                               ! F-point 
    109                DO ji = 1, jpiglo-1 
    110                   iju = jpiglo-ji+1 
    111                   ARRAY_IN(ji,ipj-1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-2,:,:,jf) 
    112                   ARRAY_IN(ji,ipj  ,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-3,:,:,jf) 
    113                END DO 
    114                ARRAY_IN(   1  ,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(    2   ,ipj-3,:,:,jf) 
    115                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(jpiglo-1,ipj-3,:,:,jf)  
    116             END SELECT 
     238               DO jl = 1, ipl; DO jk = 1, ipk 
     239                  ! 
     240                  ! last nn_hls+1 lines (from ipj to ipj-nn_hls) : full 
     241                    DO jj = 1, nn_hls+1 
     242                       ij1 = ipj            - jj + 1       ! ends at: ipj - ( nn_hls + 1 ) + 1 = ipj - nn_hls 
     243                     ij2 = ipj - 2*nn_hls + jj - 2       ! ends at: ipj - 2*nn_hls + nn_hls + 1 - 2 = ipj - nn_hls - 1 
     244                     ! 
     245                     DO ji = 1, nn_hls            ! first nn_hls points 
     246                        ii1 =                ji          ! ends at: nn_hls 
     247                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     248                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     249                     END DO 
     250                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     251                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     252                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     253                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     254                     END DO 
     255                     DO ji = 1, nn_hls            ! last nn_hls points 
     256                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     257                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     258                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     259                     END DO 
     260                  END DO 
     261                  ! 
     262               END DO; END DO 
     263            END SELECT   ! NAT_IN(jf) 
    117264            ! 
    118265         CASE ( 5 , 6 )                        ! *  North fold  F-point pivot 
     
    120267            SELECT CASE ( NAT_IN(jf)  ) 
    121268            CASE ( 'T' , 'W' )                         ! T-, W-point 
    122                DO ji = 1, jpiglo 
    123                   ijt = jpiglo-ji+1 
    124                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-1,:,:,jf) 
    125                END DO 
     269               DO jl = 1, ipl; DO jk = 1, ipk 
     270                  ! 
     271                  ! first: line number ipj-nn_hls : 3 points 
     272                    DO jj = 1, 1 
     273                     ij1 = ipj - nn_hls 
     274                     ij2 = ij1   ! same line 
     275                     ! 
     276                     DO ji = 1, 1            ! points from jpiglo/2+1 
     277                        ii1 = jpiglo/2 + ji 
     278                        ii2 = jpiglo/2 - ji + 1 
     279                        ARRAY_IN(ii1,ij1,jk,jl,jf) =              ARRAY_IN(ii2,ij2,jk,jl,jf)   ! Warning: pb with sign... 
     280                     END DO 
     281                     DO ji = 1, 1            ! points jpiglo - nn_hls 
     282                        ii1 = jpiglo - nn_hls + ji - 1 
     283                        ii2 =          nn_hls + ji 
     284                        ARRAY_IN(ii1,ij1,jk,jl,jf) =              ARRAY_IN(ii2,ij2,jk,jl,jf)   ! Warning: pb with sign... 
     285                     END DO 
     286                     DO ji = 1, 1            ! point nn_hls: redo it just in case (if e-w periodocity already done) 
     287                        !                    ! as we just changed point jpiglo - nn_hls 
     288                        ii1 = nn_hls + ji - 1 
     289                        ii2 = nn_hls + ji 
     290                        ARRAY_IN(ii1,ij1,jk,jl,jf) =              ARRAY_IN(ii2,ij2,jk,jl,jf)   ! Warning: pb with sign... 
     291                     END DO 
     292                  END DO 
     293                  ! 
     294                  ! Second: last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     295                    DO jj = 1, nn_hls 
     296                       ij1 = ipj + 1        - jj           ! ends at: ipj + 1 - nn_hls 
     297                     ij2 = ipj - 2*nn_hls + jj           ! ends at: ipj - 2*nn_hls + nn_hls = ipj - nn_hls 
     298                     ! 
     299                     DO ji = 1, nn_hls            ! first nn_hls points 
     300                        ii1 =                ji          ! ends at: nn_hls 
     301                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     302                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     303                     END DO 
     304                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     305                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     306                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     307                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     308                     END DO 
     309                     DO ji = 1, nn_hls            ! last nn_hls points 
     310                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     311                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     312                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     313                     END DO 
     314                  END DO 
     315                  ! 
     316               END DO; END DO 
    126317            CASE ( 'U' )                               ! U-point 
    127                DO ji = 1, jpiglo-1 
    128                   iju = jpiglo-ji 
    129                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-1,:,:,jf) 
    130                END DO 
    131                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpiglo-2,ipj-1,:,:,jf) 
     318               DO jl = 1, ipl; DO jk = 1, ipk 
     319                  ! 
     320                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     321                    DO jj = 1, nn_hls 
     322                       ij1 = ipj + 1        - jj           ! ends at: ipj + 1 - nn_hls 
     323                     ij2 = ipj - 2*nn_hls + jj           ! ends at: ipj - 2*nn_hls + nn_hls = ipj - nn_hls 
     324                     ! 
     325                     DO ji = 1, nn_hls-1          ! first nn_hls-1 points 
     326                        ii1 =            ji              ! ends at: nn_hls-1 
     327                        ii2 = 2*nn_hls - ji              ! ends at: 2*nn_hls - ( nn_hls - 1 ) = nn_hls + 1 
     328                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     329                     END DO 
     330                     DO ji = 1, 1                 ! point nn_hls 
     331                        ii1 = nn_hls + ji - 1 
     332                        ii2 = jpiglo - ii1 
     333                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     334                     END DO 
     335                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+1 to jpiglo - nn_hls - 1  (note: Ni0glo = jpiglo - 2*nn_hls) 
     336                        ii1 =          nn_hls + ji       ! ends at: nn_hls + ( jpiglo - 2*nn_hls - 1 ) = jpiglo - nn_hls - 1 
     337                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) = nn_hls + 1 
     338                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     339                     END DO 
     340                     DO ji = 1, 1                 ! point jpiglo - nn_hls 
     341                        ii1 = jpiglo - nn_hls + ji - 1 
     342                        ii2 = ii1 
     343                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     344                     END DO 
     345                     DO ji = 1, nn_hls            ! last nn_hls points 
     346                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     347                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - nn_hls = jpiglo - 2*nn_hls 
     348                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     349                     END DO 
     350                  END DO 
     351                  ! 
     352               END DO; END DO 
    132353            CASE ( 'V' )                               ! V-point 
    133                DO ji = 1, jpiglo 
    134                   ijt = jpiglo-ji+1 
    135                   ARRAY_IN(ji,ipj,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipj-2,:,:,jf) 
    136                END DO 
    137                DO ji = jpiglo/2+1, jpiglo 
    138                   ijt = jpiglo-ji+1 
    139                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(ijt,ipjm1,:,:,jf) 
    140                END DO 
     354               DO jl = 1, ipl; DO jk = 1, ipk 
     355                  ! 
     356                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     357                    DO jj = 1, nn_hls 
     358                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     359                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     360                     ! 
     361                     DO ji = 1, nn_hls            ! first nn_hls points 
     362                        ii1 =                ji          ! ends at: nn_hls 
     363                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     364                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     365                     END DO 
     366                     DO ji = 1, Ni0glo            ! points from nn_hls to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     367                        ii1 = nn_hls          + ji       ! ends at: nn_hls + jpiglo - 2*nn_hls = jpiglo - nn_hls 
     368                        ii2 = jpiglo - nn_hls - ji + 1   ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls ) + 1 = nn_hls + 1 
     369                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     370                     END DO 
     371                     DO ji = 1, nn_hls            ! last nn_hls points 
     372                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     373                        ii2 = jpiglo - nn_hls + 1 - ji   ! ends at: jpiglo - nn_hls + 1 - nn_hls = jpiglo - 2*nn_hls + 1 
     374                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     375                     END DO 
     376                  END DO    
     377                  ! 
     378                  ! line number ipj-nn_hls : right half 
     379                    DO jj = 1, 1 
     380                     ij1 = ipj - nn_hls 
     381                     ij2 = ij1   ! same line 
     382                     ! 
     383                     DO ji = 1, Ni0glo/2          ! points from jpiglo/2+1 to jpiglo - nn_hls   (note: Ni0glo = jpiglo - 2*nn_hls) 
     384                        ii1 = jpiglo/2 + ji              ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls) = jpiglo - nn_hls 
     385                        ii2 = jpiglo/2 - ji + 1          ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls) + 1 = nn_hls + 1 
     386                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     387                     END DO 
     388                     DO ji = 1, nn_hls            ! first nn_hls points: redo them just in case (if e-w periodocity already done) 
     389                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hls   
     390                        ii1 =                ji          ! ends at: nn_hls 
     391                        ii2 = 2*nn_hls + 1 - ji          ! ends at: 2*nn_hls + 1 - nn_hls = nn_hls + 1 
     392                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     393                     END DO 
     394                     !                            ! last nn_hls points: have been / will done by e-w periodicity  
     395                  END DO 
     396                  ! 
     397               END DO; END DO 
    141398            CASE ( 'F' )                               ! F-point 
    142                DO ji = 1, jpiglo-1 
    143                   iju = jpiglo-ji 
    144                   ARRAY_IN(ji,ipj  ,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipj-2,:,:,jf) 
    145                END DO 
    146                ARRAY_IN(jpiglo,ipj,:,:,jf) = SGN_IN(jf)   * ARRAY_IN(jpiglo-2,ipj-2,:,:,jf) 
    147                DO ji = jpiglo/2+1, jpiglo-1 
    148                   iju = jpiglo-ji 
    149                   ARRAY_IN(ji,ipjm1,:,:,jf) = SGN_IN(jf)  * ARRAY_IN(iju,ipjm1,:,:,jf) 
    150                END DO 
    151             END SELECT 
     399               DO jl = 1, ipl; DO jk = 1, ipk 
     400                  ! 
     401                  ! last nn_hls lines (from ipj to ipj-nn_hls+1) : full 
     402                    DO jj = 1, nn_hls 
     403                       ij1 = ipj            - jj + 1       ! ends at: ipj - nn_hls + 1 
     404                     ij2 = ipj - 2*nn_hls + jj - 1       ! ends at: ipj - 2*nn_hls + nn_hls - 1 = ipj - nn_hls - 1 
     405                     ! 
     406                     DO ji = 1, nn_hls-1          ! first nn_hls-1 points 
     407                        ii1 =            ji              ! ends at: nn_hls-1 
     408                        ii2 = 2*nn_hls - ji              ! ends at: 2*nn_hls - ( nn_hls - 1 ) = nn_hls + 1 
     409                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     410                     END DO 
     411                     DO ji = 1, 1                 ! point nn_hls 
     412                        ii1 = nn_hls + ji - 1 
     413                        ii2 = jpiglo - ii1 
     414                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     415                     END DO 
     416                     DO ji = 1, Ni0glo - 1        ! points from nn_hls+1 to jpiglo - nn_hls - 1  (note: Ni0glo = jpiglo - 2*nn_hls) 
     417                        ii1 =          nn_hls + ji       ! ends at: nn_hls + ( jpiglo - 2*nn_hls - 1 ) = jpiglo - nn_hls - 1 
     418                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - ( jpiglo - 2*nn_hls - 1 ) = nn_hls + 1 
     419                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     420                     END DO 
     421                     DO ji = 1, 1                 ! point jpiglo - nn_hls 
     422                        ii1 = jpiglo - nn_hls + ji - 1 
     423                        ii2 = ii1 
     424                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     425                     END DO 
     426                     DO ji = 1, nn_hls            ! last nn_hls points 
     427                        ii1 = jpiglo - nn_hls + ji       ! ends at: jpiglo - nn_hls + nn_hls = jpiglo 
     428                        ii2 = jpiglo - nn_hls - ji       ! ends at: jpiglo - nn_hls - nn_hls = jpiglo - 2*nn_hls 
     429                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     430                     END DO 
     431                  END DO    
     432                  ! 
     433                  ! line number ipj-nn_hls : right half 
     434                    DO jj = 1, 1 
     435                     ij1 = ipj - nn_hls 
     436                     ij2 = ij1   ! same line 
     437                     ! 
     438                     DO ji = 1, Ni0glo/2-1        ! points from jpiglo/2+1 to jpiglo - nn_hls-1  (note: Ni0glo = jpiglo - 2*nn_hls) 
     439                        ii1 = jpiglo/2 + ji              ! ends at: jpiglo/2 + (jpiglo/2 - nn_hls) = jpiglo - nn_hls 
     440                        ii2 = jpiglo/2 - ji              ! ends at: jpiglo/2 - (jpiglo/2 - nn_hls - 1 ) = nn_hls + 1 
     441                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     442                     END DO 
     443                     DO ji = 1, nn_hls-1          ! first nn_hls-1 points: redo them just in case (if e-w periodocity already done) 
     444                        !                         ! as we just changed points jpiglo-2nn_hls+1 to jpiglo-nn_hl-1   
     445                        ii1 =            ji              ! ends at: nn_hls 
     446                        ii2 = 2*nn_hls - ji              ! ends at: 2*nn_hls - ( nn_hls - 1 ) = nn_hls + 1 
     447                        ARRAY_IN(ii1,ij1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ii2,ij2,jk,jl,jf) 
     448                     END DO 
     449                     !                            ! last nn_hls points: have been / will done by e-w periodicity  
     450                  END DO 
     451                  ! 
     452               END DO; END DO 
     453            END SELECT   ! NAT_IN(jf) 
    152454            ! 
    153          CASE DEFAULT                           ! *  closed : the code probably never go through 
    154             ! 
    155             SELECT CASE ( NAT_IN(jf) ) 
    156             CASE ( 'T' , 'U' , 'V' , 'W' )             ! T-, U-, V-, W-points 
    157                ARRAY_IN(:, 1 ,:,:,jf) = 0._wp 
    158                ARRAY_IN(:,ipj,:,:,jf) = 0._wp 
    159             CASE ( 'F' )                               ! F-point 
    160                ARRAY_IN(:,ipj,:,:,jf) = 0._wp 
    161             END SELECT 
    162             ! 
    163          END SELECT     !  npolj 
     455         END SELECT   ! npolj 
    164456         ! 
    165       END DO 
     457      END DO   ! ipf 
    166458      ! 
    167459   END SUBROUTINE ROUTINE_NFD 
    168460 
     461#undef PRECISION 
    169462#undef ARRAY_TYPE 
    170463#undef ARRAY_IN 
    171464#undef NAT_IN 
    172465#undef SGN_IN 
     466#undef J_SIZE 
    173467#undef K_SIZE 
    174468#undef L_SIZE 
  • utils/tools/DOMAINcfg/src/lbc_nfd_nogather_generic.h90

    r12414 r14623  
    44#   define F_SIZE(ptab)             kfld 
    55#   if defined DIM_2d 
    6 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D),INTENT(inout)::ptab(f) 
     6#      if defined SINGLE_PRECISION 
     7#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f) 
     8#      else 
     9#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f) 
     10#      endif  
    711#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
    812#      define K_SIZE(ptab)             1 
     
    1014#   endif 
    1115#   if defined DIM_3d 
    12 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D),INTENT(inout)::ptab(f) 
     16#      if defined SINGLE_PRECISION 
     17#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f) 
     18#      else 
     19#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f) 
     20#      endif  
    1321#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
    1422#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
     
    1624#   endif 
    1725#   if defined DIM_4d 
    18 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D),INTENT(inout)::ptab(f) 
     26#      if defined SINGLE_PRECISION 
     27#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f) 
     28#      else 
     29#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f) 
     30#      endif  
    1931#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
    2032#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
    2133#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4) 
    2234#   endif 
    23 #   define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D),INTENT(inout)::ptab2(f) 
     35#   if defined SINGLE_PRECISION 
     36#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_sp),INTENT(inout)::ptab2(f) 
     37#   else 
     38#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_dp),INTENT(inout)::ptab2(f) 
     39#   endif 
    2440#   define J_SIZE(ptab2)            SIZE(ptab2(1)%pt4d,2) 
    2541#   define ARRAY2_IN(i,j,k,l,f)     ptab2(f)%pt4d(i,j,k,l) 
     
    4460#      define L_SIZE(ptab)          SIZE(ptab,4) 
    4561#   endif 
    46 #   define ARRAY2_IN(i,j,k,l,f)  ptab2(i,j,k,l) 
    4762#   define J_SIZE(ptab2)             SIZE(ptab2,2) 
    48 #   define ARRAY_TYPE(i,j,k,l,f)     REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
    49 #   define ARRAY2_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f) 
    50 #endif 
    51  
     63#   define ARRAY2_IN(i,j,k,l,f)   ptab2(i,j,k,l) 
     64#   if defined SINGLE_PRECISION 
     65#      define ARRAY_TYPE(i,j,k,l,f)     REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     66#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f) 
     67#   else 
     68#      define ARRAY_TYPE(i,j,k,l,f)     REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f) 
     69#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f) 
     70#   endif 
     71#   endif 
     72#   ifdef SINGLE_PRECISION 
     73#      define PRECISION sp 
     74#   else 
     75#      define PRECISION dp 
     76#   endif 
    5277   SUBROUTINE ROUTINE_NFD( ptab, ptab2, cd_nat, psgn, kfld ) 
    5378      !!---------------------------------------------------------------------- 
     
    5782      !! 
    5883      !!---------------------------------------------------------------------- 
    59       ARRAY_TYPE(:,:,:,:,:)                             ! array or pointer of arrays on which the boundary condition is applied 
    60       ARRAY2_TYPE(:,:,:,:,:)                            ! array or pointer of arrays on which the boundary condition is applied 
     84      ARRAY_TYPE(:,:,:,:,:) 
     85      ARRAY2_TYPE(:,:,:,:,:)  
    6186      CHARACTER(len=1) , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
    6287      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
    6388      INTEGER, OPTIONAL, INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    6489      ! 
    65       INTEGER  ::    ji,  jj,   jk,     jl,   jh,  jf   ! dummy loop indices 
    66       INTEGER  ::   ipi, ipj,  ipk,    ipl,  ipf        ! dimension of the input array 
    67       INTEGER  ::   ijt, iju, ijpj, ijpjp1, ijta, ijua, jia, startloop, endloop 
     90      INTEGER  ::    ji,  jj,   jk, jn, ii,   jl,   jh,  jf   ! dummy loop indices 
     91      INTEGER  ::   ipi, ipj,  ipk,    ipl,  ipf, iij, ijj   ! dimension of the input array 
     92      INTEGER  ::   ijt, iju, ijta, ijua, jia, startloop, endloop 
    6893      LOGICAL  ::   l_fast_exchanges 
    6994      !!---------------------------------------------------------------------- 
     
    7499      ! 
    75100      ! Security check for further developments 
    76       IF ( ipf > 1 ) THEN 
    77         write(6,*) 'lbc_nfd_nogather: multiple fields not allowed. Revise implementation'  
    78         write(6,*) 'You should not be there...'  
    79         STOP 
    80       ENDIF 
    81       ! 
    82       ijpj   = 1    ! index of first modified line  
    83       ijpjp1 = 2    ! index + 1 
    84        
     101      IF ( ipf > 1 ) CALL ctl_stop( 'STOP', 'lbc_nfd_nogather: multiple fields not allowed. Revise implementation...' ) 
    85102      ! 2nd dimension determines exchange speed 
    86103      IF (ipj == 1 ) THEN 
     
    99116            ! 
    100117            CASE ( 'T' , 'W' )                         ! T-, W-point 
    101                IF ( nimpp /= 1 ) THEN   ;   startloop = 1 
    102                ELSE                     ;   startloop = 2 
    103                ENDIF 
    104                ! 
    105                DO jl = 1, ipl; DO jk = 1, ipk 
    106                   DO ji = startloop, nlci 
    107                      ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
    108                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
     118               IF ( nimpp /= 1 ) THEN  ;  startloop = 1  
     119               ELSE                    ;  startloop = 1 + nn_hls 
     120               ENDIF 
     121               ! 
     122               DO jl = 1, ipl; DO jk = 1, ipk 
     123                    DO jj = 1, nn_hls 
     124                       ijj = jpj -jj +1 
     125                     DO ji = startloop, jpi 
     126                     ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
     127                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     128                     END DO 
    109129                  END DO 
    110130               END DO; END DO 
    111131               IF( nimpp == 1 ) THEN 
    112132                  DO jl = 1, ipl; DO jk = 1, ipk 
    113                      ARRAY_IN(1,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(3,nlcj-2,jk,jl,jf) 
    114                   END DO; END DO 
    115                ENDIF 
    116                ! 
    117                IF ( .NOT. l_fast_exchanges ) THEN 
    118                   IF( nimpp >= jpiglo/2+1 ) THEN 
     133                     DO jj = 1, nn_hls 
     134                     ijj = jpj -jj +1 
     135                     DO ii = 0, nn_hls-1 
     136                        ARRAY_IN(ii+1,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii+1,jpj-2*nn_hls+jj-1,jk,jl,jf) 
     137                     END DO 
     138                     END DO 
     139                  END DO; END DO 
     140               ENDIF               
     141               ! 
     142               IF ( .NOT. l_fast_exchanges ) THEN 
     143                  IF( nimpp >= Ni0glo/2+2 ) THEN 
    119144                     startloop = 1 
    120                   ELSEIF( nimpp+nlci-1 >= jpiglo/2+1 .AND. nimpp < jpiglo/2+1 ) THEN 
    121                      startloop = jpiglo/2+1 - nimpp + 1 
    122                   ELSE 
    123                      startloop = nlci + 1 
    124                   ENDIF 
    125                   IF( startloop <= nlci ) THEN 
     145                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN 
     146                     startloop = Ni0glo/2+2 - nimpp + nn_hls 
     147                  ELSE 
     148                     startloop = jpi + 1 
     149                  ENDIF 
     150                  IF( startloop <= jpi ) THEN 
    126151                     DO jl = 1, ipl; DO jk = 1, ipk 
    127                         DO ji = startloop, nlci 
    128                            ijt  = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
     152                        DO ji = startloop, jpi 
     153                           ijt  = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
    129154                           jia  = ji + nimpp - 1 
    130155                           ijta = jpiglo - jia + 2 
    131156                           IF( ijta >= startloop+nimpp-1 .AND. ijta < jia ) THEN 
    132                               ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijta-nimpp+1,nlcj-1,jk,jl,jf) 
     157                              ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijta-nimpp+nn_hls,jpj-nn_hls,jk,jl,jf) 
    133158                           ELSE 
    134                               ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpjp1,jk,jl,jf) 
     159                              ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,nn_hls+1,jk,jl,jf) 
    135160                           ENDIF 
    136161                        END DO 
     
    138163                  ENDIF 
    139164               ENDIF 
    140  
    141165            CASE ( 'U' )                                     ! U-point 
    142                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    143                   endloop = nlci 
     166               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     167                  endloop = jpi 
    144168               ELSE 
    145                   endloop = nlci - 1 
    146                ENDIF 
    147                DO jl = 1, ipl; DO jk = 1, ipk 
    148                   DO ji = 1, endloop 
    149                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    150                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
     169                  endloop = jpi - nn_hls 
     170               ENDIF 
     171               DO jl = 1, ipl; DO jk = 1, ipk 
     172        DO jj = 1, nn_hls 
     173              ijj = jpj -jj +1 
     174                     DO ji = 1, endloop 
     175                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     176                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     177                     END DO 
    151178                  END DO 
    152179               END DO; END DO 
    153180               IF (nimpp .eq. 1) THEN 
    154                   ARRAY_IN(1,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2,nlcj-2,:,:,jf) 
    155                ENDIF 
    156                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    157                   ARRAY_IN(nlci,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(nlci-1,nlcj-2,:,:,jf) 
    158                ENDIF 
    159                ! 
    160                IF ( .NOT. l_fast_exchanges ) THEN 
    161                   IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    162                      endloop = nlci 
    163                   ELSE 
    164                      endloop = nlci - 1 
    165                   ENDIF 
    166                   IF( nimpp >= jpiglo/2 ) THEN 
    167                      startloop = 1 
    168                      ELSEIF( ( nimpp+nlci-1 >= jpiglo/2 ) .AND. ( nimpp < jpiglo/2 ) ) THEN 
    169                      startloop = jpiglo/2 - nimpp + 1 
     181        DO jj = 1, nn_hls 
     182           ijj = jpj -jj +1 
     183           DO ii = 0, nn_hls-1 
     184         ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     185           END DO 
     186                  END DO 
     187               ENDIF 
     188               IF((nimpp + jpi - 1) .eq. jpiglo) THEN 
     189                  DO jj = 1, nn_hls 
     190                       ijj = jpj -jj +1 
     191         DO ii = 1, nn_hls 
     192               ARRAY_IN(jpi-ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     193         END DO 
     194        END DO 
     195               ENDIF 
     196               ! 
     197               IF ( .NOT. l_fast_exchanges ) THEN 
     198                  IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     199                     endloop = jpi 
     200                  ELSE 
     201                     endloop = jpi - nn_hls 
     202                  ENDIF 
     203                  IF( nimpp >= Ni0glo/2+1 ) THEN 
     204                     startloop = nn_hls 
     205                  ELSEIF( ( nimpp + jpi - 1 >= Ni0glo/2+1 ) .AND. ( nimpp < Ni0glo/2+1 ) ) THEN 
     206                     startloop = Ni0glo/2+1 - nimpp + nn_hls  
    170207                  ELSE 
    171208                     startloop = endloop + 1 
     
    174211                  DO jl = 1, ipl; DO jk = 1, ipk 
    175212                     DO ji = startloop, endloop 
    176                         iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    177                         jia = ji + nimpp - 1 
    178                         ijua = jpiglo - jia + 1 
     213                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     214                        jia = ji + nimpp - 1  
     215                        ijua = jpiglo - jia + 1  
    179216                        IF( ijua >= startloop+nimpp-1 .AND. ijua < jia ) THEN 
    180                            ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijua-nimpp+1,nlcj-1,jk,jl,jf) 
     217                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(ijua-nimpp+1,jpj-nn_hls,jk,jl,jf) 
    181218                        ELSE 
    182                            ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpjp1,jk,jl,jf) 
     219                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,nn_hls+1,jk,jl,jf) 
    183220                        ENDIF 
    184221                     END DO 
     
    189226            CASE ( 'V' )                                     ! V-point 
    190227               IF( nimpp /= 1 ) THEN 
    191                  startloop = 1 
     228                 startloop = 1  
    192229               ELSE 
    193                  startloop = 2 
    194                ENDIF 
    195                IF ( .NOT. l_fast_exchanges ) THEN 
    196                   DO jl = 1, ipl; DO jk = 1, ipk 
    197                      DO ji = startloop, nlci 
    198                         ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
    199                         ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpjp1,jk,jl,jf) 
    200                      END DO 
    201                   END DO; END DO 
    202                ENDIF 
    203                DO jl = 1, ipl; DO jk = 1, ipk 
    204                   DO ji = startloop, nlci 
    205                      ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4 
    206                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
     230                 startloop = 1 + nn_hls 
     231               ENDIF 
     232               IF ( .NOT. l_fast_exchanges ) THEN 
     233                  DO jl = 1, ipl; DO jk = 1, ipk 
     234                       DO jj = 2, nn_hls+1 
     235                     ijj = jpj -jj +1 
     236                        DO ji = startloop, jpi 
     237                           ijt=jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
     238                           ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     239                        END DO 
     240                    END DO 
     241                  END DO; END DO 
     242               ENDIF 
     243               DO jl = 1, ipl; DO jk = 1, ipk 
     244                  DO ji = startloop, jpi 
     245                     ijt=jpiglo - ji - nimpp - nfimpp(isendto(1)) + 4 
     246                     ARRAY_IN(ji,jpj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,1,jk,jl,jf) 
    207247                  END DO 
    208248               END DO; END DO 
    209249               IF (nimpp .eq. 1) THEN 
    210                   ARRAY_IN(1,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(3,nlcj-3,:,:,jf) 
     250        DO jj = 1, nn_hls 
     251                       ijj = jpj-jj+1 
     252                       DO ii = 0, nn_hls-1 
     253                        ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii+1,jpj-2*nn_hls+jj-1,:,:,jf) 
     254           END DO 
     255        END DO 
    211256               ENDIF 
    212257            CASE ( 'F' )                                     ! F-point 
    213                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    214                   endloop = nlci 
     258               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     259                  endloop = jpi 
    215260               ELSE 
    216                   endloop = nlci - 1 
    217                ENDIF 
    218                IF ( .NOT. l_fast_exchanges ) THEN 
    219                   DO jl = 1, ipl; DO jk = 1, ipk 
    220                      DO ji = 1, endloop 
    221                         iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    222                         ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpjp1,jk,jl,jf) 
    223                      END DO 
     261                  endloop = jpi - nn_hls 
     262               ENDIF 
     263               IF ( .NOT. l_fast_exchanges ) THEN 
     264                  DO jl = 1, ipl; DO jk = 1, ipk 
     265                       DO jj = 2, nn_hls+1 
     266                     ijj = jpj -jj +1 
     267                        DO ji = 1, endloop 
     268                           iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     269                           ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     270                        END DO 
     271                    END DO 
    224272                  END DO; END DO 
    225273               ENDIF 
    226274               DO jl = 1, ipl; DO jk = 1, ipk 
    227275                  DO ji = 1, endloop 
    228                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    229                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
    230                   END DO 
    231                END DO; END DO 
    232                IF (nimpp .eq. 1) THEN 
    233                   ARRAY_IN(1,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2,nlcj-3,:,:,jf) 
    234                   IF ( .NOT. l_fast_exchanges ) & 
    235                      ARRAY_IN(1,nlcj-1,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2,nlcj-2,:,:,jf) 
    236                ENDIF 
    237                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    238                   ARRAY_IN(nlci,nlcj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(nlci-1,nlcj-3,:,:,jf) 
    239                   IF ( .NOT. l_fast_exchanges ) & 
    240                      ARRAY_IN(nlci,nlcj-1,:,:,jf) = SGN_IN(jf) * ARRAY_IN(nlci-1,nlcj-2,:,:,jf) 
    241                ENDIF 
    242                ! 
    243             END SELECT 
     276                     iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     277                     ARRAY_IN(ji,jpj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,1,jk,jl,jf) 
     278                  END DO 
     279               END DO; END DO 
     280      IF (nimpp .eq. 1) THEN                
     281         DO ii = 1, nn_hls 
     282                 ARRAY_IN(ii,jpj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls-1,:,:,jf) 
     283         END DO 
     284         IF ( .NOT. l_fast_exchanges ) THEN 
     285            DO jj = 1, nn_hls 
     286                      ijj = jpj -jj 
     287                      DO ii = 0, nn_hls-1 
     288                         ARRAY_IN(ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(2*nn_hls-ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     289                   END DO 
     290                      END DO 
     291                     ENDIF 
     292      ENDIF 
     293      IF((nimpp + jpi - 1 ) .eq. jpiglo) THEN 
     294                   DO ii = 1, nn_hls 
     295                 ARRAY_IN(jpi-ii+1,jpj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls-1,:,:,jf) 
     296         END DO 
     297         IF ( .NOT. l_fast_exchanges ) THEN 
     298            DO jj = 1, nn_hls 
     299                           ijj = jpj -jj 
     300                      DO ii = 1, nn_hls 
     301                         ARRAY_IN(jpi-ii+1,ijj,:,:,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii,jpj-2*nn_hls+jj-1,:,:,jf) 
     302                         END DO 
     303                      END DO 
     304                     ENDIF 
     305                  ENDIF 
     306                  ! 
     307       END SELECT 
    244308            ! 
    245309         CASE ( 5, 6 )                        ! *  North fold  F-point pivot 
     
    248312            CASE ( 'T' , 'W' )                               ! T-, W-point 
    249313               DO jl = 1, ipl; DO jk = 1, ipk 
    250                   DO ji = 1, nlci 
    251                      ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    252                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
    253                   END DO 
     314        DO jj = 1, nn_hls 
     315           ijj = jpj-jj+1 
     316           DO ji = 1, jpi 
     317                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     318                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     319                     END DO 
     320        END DO 
    254321               END DO; END DO 
    255322               ! 
    256323            CASE ( 'U' )                                     ! U-point 
    257                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    258                   endloop = nlci 
     324               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     325                  endloop = jpi 
    259326               ELSE 
    260                   endloop = nlci - 1 
    261                ENDIF 
    262                DO jl = 1, ipl; DO jk = 1, ipk 
    263                   DO ji = 1, endloop 
    264                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2 
    265                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
    266                   END DO 
    267                END DO; END DO 
    268                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    269                   DO jl = 1, ipl; DO jk = 1, ipk 
    270                      ARRAY_IN(nlci,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(nlci-2,nlcj-1,jk,jl,jf) 
     327                  endloop = jpi - nn_hls 
     328               ENDIF 
     329               DO jl = 1, ipl; DO jk = 1, ipk 
     330        DO jj = 1, nn_hls 
     331           ijj = jpj-jj+1 
     332                     DO ji = 1, endloop 
     333                        iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2 
     334                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     335                     END DO 
     336                  END DO 
     337               END DO; END DO 
     338               IF(nimpp + jpi - 1 .eq. jpiglo) THEN 
     339                  DO jl = 1, ipl; DO jk = 1, ipk 
     340                     DO jj = 1, nn_hls 
     341                          ijj = jpj-jj+1 
     342                        DO ii = 1, nn_hls 
     343            iij = jpi-ii+1 
     344                           ARRAY_IN(iij,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii-1,jpj-2*nn_hls+jj,jk,jl,jf) 
     345                        END DO 
     346                     END DO 
    271347                  END DO; END DO 
    272348               ENDIF 
     
    274350            CASE ( 'V' )                                     ! V-point 
    275351               DO jl = 1, ipl; DO jk = 1, ipk 
    276                   DO ji = 1, nlci 
    277                      ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    278                      ARRAY_IN(ji,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpj,jk,jl,jf) 
     352        DO jj = 1, nn_hls 
     353           ijj = jpj -jj +1 
     354                     DO ji = 1, jpi 
     355                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     356                        ARRAY_IN(ji,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,jj,jk,jl,jf) 
     357                     END DO 
    279358                  END DO 
    280359               END DO; END DO 
    281360 
    282361               IF ( .NOT. l_fast_exchanges ) THEN 
    283                   IF( nimpp >= jpiglo/2+1 ) THEN 
     362                  IF( nimpp >= Ni0glo/2+2 ) THEN 
    284363                     startloop = 1 
    285                   ELSEIF( nimpp+nlci-1 >= jpiglo/2+1 .AND. nimpp < jpiglo/2+1 ) THEN 
    286                      startloop = jpiglo/2+1 - nimpp + 1 
    287                   ELSE 
    288                      startloop = nlci + 1 
    289                   ENDIF 
    290                   IF( startloop <= nlci ) THEN 
    291                   DO jl = 1, ipl; DO jk = 1, ipk 
    292                      DO ji = startloop, nlci 
    293                         ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3 
    294                         ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,ijpjp1,jk,jl,jf) 
    295                      END DO 
     364                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN 
     365                     startloop = Ni0glo/2+2 - nimpp + nn_hls 
     366                  ELSE 
     367                     startloop = jpi + 1 
     368                  ENDIF 
     369                  IF( startloop <= jpi ) THEN 
     370                  DO jl = 1, ipl; DO jk = 1, ipk 
     371                        DO ji = startloop, jpi 
     372                        ijt = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 3 
     373                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(ijt,nn_hls+1,jk,jl,jf) 
     374                        END DO 
    296375                  END DO; END DO 
    297376                  ENDIF 
     
    299378               ! 
    300379            CASE ( 'F' )                               ! F-point 
    301                IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    302                   endloop = nlci 
     380               IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     381                  endloop = jpi 
    303382               ELSE 
    304                   endloop = nlci - 1 
    305                ENDIF 
    306                DO jl = 1, ipl; DO jk = 1, ipk 
    307                   DO ji = 1, endloop 
    308                      iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2 
    309                      ARRAY_IN(ji,nlcj ,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpj,jk,jl,jf) 
    310                   END DO 
    311                END DO; END DO 
    312                IF((nimpp + nlci - 1) .eq. jpiglo) THEN 
    313                   DO jl = 1, ipl; DO jk = 1, ipk 
    314                      ARRAY_IN(nlci,nlcj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(nlci-2,nlcj-2,jk,jl,jf) 
    315                   END DO; END DO 
    316                ENDIF 
    317                ! 
    318                IF ( .NOT. l_fast_exchanges ) THEN 
    319                   IF( nimpp + nlci - 1 /= jpiglo ) THEN 
    320                      endloop = nlci 
    321                   ELSE 
    322                      endloop = nlci - 1 
    323                   ENDIF 
    324                   IF( nimpp >= jpiglo/2+1 ) THEN 
    325                      startloop = 1 
    326                   ELSEIF( nimpp+nlci-1 >= jpiglo/2+1 .AND. nimpp < jpiglo/2+1 ) THEN 
    327                      startloop = jpiglo/2+1 - nimpp + 1 
     383                  endloop = jpi - nn_hls 
     384               ENDIF 
     385               DO jl = 1, ipl; DO jk = 1, ipk 
     386        DO jj = 1, nn_hls 
     387          ijj = jpj -jj +1 
     388                    DO ji = 1, endloop 
     389                       iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2 
     390                       ARRAY_IN(ji,ijj ,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,jj,jk,jl,jf) 
     391                     END DO 
     392                  END DO 
     393               END DO; END DO 
     394               IF((nimpp + jpi - 1) .eq. jpiglo) THEN 
     395                  DO jl = 1, ipl; DO jk = 1, ipk 
     396                     DO jj = 1, nn_hls 
     397                        ijj = jpj -jj +1 
     398                        DO ii = 1, nn_hls 
     399            iij = jpi -ii+1 
     400                           ARRAY_IN(iij,ijj,jk,jl,jf) = SGN_IN(jf) * ARRAY_IN(jpi-2*nn_hls+ii-1,jpj-2*nn_hls+jj-1,jk,jl,jf) 
     401                        END DO 
     402                     END DO 
     403                  END DO; END DO 
     404               ENDIF 
     405               ! 
     406               IF ( .NOT. l_fast_exchanges ) THEN 
     407                  IF( nimpp + jpi - 1 /= jpiglo ) THEN 
     408                     endloop = jpi 
     409                  ELSE 
     410                     endloop = jpi - nn_hls 
     411                  ENDIF 
     412                  IF( nimpp >= Ni0glo/2+2 ) THEN 
     413                     startloop = 1  
     414                  ELSEIF( nimpp+jpi-1 >= Ni0glo/2+2 .AND. nimpp < Ni0glo/2+2 ) THEN 
     415                     startloop = Ni0glo/2+2 - nimpp + nn_hls 
    328416                  ELSE 
    329417                     startloop = endloop + 1 
     
    332420                     DO jl = 1, ipl; DO jk = 1, ipk 
    333421                        DO ji = startloop, endloop 
    334                            iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2 
    335                            ARRAY_IN(ji,nlcj-1,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,ijpjp1,jk,jl,jf) 
     422                           iju = jpiglo - ji - nimpp - nfimpp(isendto(1)) + 2 
     423                           ARRAY_IN(ji,jpj-nn_hls,jk,jl,jf) = SGN_IN(jf) * ARRAY2_IN(iju,nn_hls+1,jk,jl,jf) 
    336424                        END DO 
    337425                     END DO; END DO 
     
    349437      END DO            ! End jf loop 
    350438   END SUBROUTINE ROUTINE_NFD 
     439#undef PRECISION 
    351440#undef ARRAY_TYPE 
    352441#undef ARRAY_IN 
  • utils/tools/DOMAINcfg/src/lbclnk.F90

    r13204 r14623  
    77   !!   NEMO     1.0  ! 2002-09  (G. Madec)  F90: Free form and module 
    88   !!            3.2  ! 2009-03  (R. Benshila)  External north fold treatment   
    9    !!            3.5  ! 2012     (S.Mocavero, I. Epicoco)  optimization of BDY comm. 
     9   !!            3.5  ! 2012     (S.Mocavero, I. Epicoco)  optimization of BDY comm. via lbc_bdy_lnk and lbc_obc_lnk 
    1010   !!            3.4  ! 2012-12  (R. Bourdalle-Badie, G. Reffray)  add a C1D case   
    1111   !!            3.6  ! 2015-06  (O. Tintó and M. Castrillo)  add lbc_lnk_multi   
     
    1414   !!             -   ! 2017-05  (G. Madec) create generic.h90 files to generate all lbc and north fold routines 
    1515   !!---------------------------------------------------------------------- 
    16 #if defined key_mpp_mpi 
    17    !!---------------------------------------------------------------------- 
    18    !!   'key_mpp_mpi'             MPI massively parallel processing library 
    19    !!---------------------------------------------------------------------- 
    2016   !!           define the generic interfaces of lib_mpp routines 
    2117   !!---------------------------------------------------------------------- 
    2218   !!   lbc_lnk       : generic interface for mpp_lnk_3d and mpp_lnk_2d routines defined in lib_mpp 
    23    !!---------------------------------------------------------------------- 
    24    USE par_oce        ! ocean dynamics and tracers    
     19   !!   lbc_bdy_lnk   : generic interface for mpp_lnk_bdy_2d and mpp_lnk_bdy_3d routines defined in lib_mpp 
     20   !!---------------------------------------------------------------------- 
     21   USE dom_oce        ! ocean space and time domain 
    2522   USE lib_mpp        ! distributed memory computing library 
    2623   USE lbcnfd         ! north fold 
     24   USE in_out_manager ! I/O manager 
     25 
     26   IMPLICIT NONE 
     27   PRIVATE 
    2728 
    2829   INTERFACE lbc_lnk 
    29       MODULE PROCEDURE   mpp_lnk_2d      , mpp_lnk_3d      , mpp_lnk_4d 
     30      MODULE PROCEDURE   mpp_lnk_2d_sp   , mpp_lnk_3d_sp   , mpp_lnk_4d_sp 
     31      MODULE PROCEDURE   mpp_lnk_2d_dp   , mpp_lnk_3d_dp   , mpp_lnk_4d_dp 
    3032   END INTERFACE 
    3133   INTERFACE lbc_lnk_ptr 
    32       MODULE PROCEDURE   mpp_lnk_2d_ptr  , mpp_lnk_3d_ptr  , mpp_lnk_4d_ptr 
     34      MODULE PROCEDURE   mpp_lnk_2d_ptr_sp , mpp_lnk_3d_ptr_sp , mpp_lnk_4d_ptr_sp 
     35      MODULE PROCEDURE   mpp_lnk_2d_ptr_dp , mpp_lnk_3d_ptr_dp , mpp_lnk_4d_ptr_dp 
    3336   END INTERFACE 
    3437   INTERFACE lbc_lnk_multi 
    35       MODULE PROCEDURE   lbc_lnk_2d_multi, lbc_lnk_3d_multi, lbc_lnk_4d_multi 
     38      MODULE PROCEDURE   lbc_lnk_2d_multi_sp , lbc_lnk_3d_multi_sp, lbc_lnk_4d_multi_sp 
     39      MODULE PROCEDURE   lbc_lnk_2d_multi_dp , lbc_lnk_3d_multi_dp, lbc_lnk_4d_multi_dp 
    3640   END INTERFACE 
    3741   ! 
    3842   INTERFACE lbc_lnk_icb 
    39       MODULE PROCEDURE mpp_lnk_2d_icb 
     43      MODULE PROCEDURE mpp_lnk_2d_icb_dp, mpp_lnk_2d_icb_sp 
     44   END INTERFACE 
     45 
     46   INTERFACE mpp_nfd 
     47      MODULE PROCEDURE   mpp_nfd_2d_sp    , mpp_nfd_3d_sp    , mpp_nfd_4d_sp 
     48      MODULE PROCEDURE   mpp_nfd_2d_dp    , mpp_nfd_3d_dp    , mpp_nfd_4d_dp 
     49      MODULE PROCEDURE   mpp_nfd_2d_ptr_sp, mpp_nfd_3d_ptr_sp, mpp_nfd_4d_ptr_sp 
     50      MODULE PROCEDURE   mpp_nfd_2d_ptr_dp, mpp_nfd_3d_ptr_dp, mpp_nfd_4d_ptr_dp 
     51       
    4052   END INTERFACE 
    4153 
     
    4456   PUBLIC   lbc_lnk_icb   ! iceberg lateral boundary conditions 
    4557 
     58#if   defined key_mpp_mpi 
     59!$AGRIF_DO_NOT_TREAT 
     60   INCLUDE 'mpif.h' 
     61!$AGRIF_END_DO_NOT_TREAT 
     62#endif 
     63 
     64   INTEGER, PUBLIC, PARAMETER ::   jpfillnothing = 1 
     65   INTEGER, PUBLIC, PARAMETER ::   jpfillcst     = 2 
     66   INTEGER, PUBLIC, PARAMETER ::   jpfillcopy    = 3 
     67   INTEGER, PUBLIC, PARAMETER ::   jpfillperio   = 4 
     68   INTEGER, PUBLIC, PARAMETER ::   jpfillmpi     = 5 
     69 
     70   !! * Substitutions 
     71#  include "do_loop_substitute.h90" 
    4672   !!---------------------------------------------------------------------- 
    4773   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    48    !! $Id: lbclnk.F90 10425 2018-12-19 21:54:16Z smasson $ 
     74   !! $Id: lbclnk.F90 13226 2020-07-02 14:24:31Z orioltp $ 
    4975   !! Software governed by the CeCILL license (see ./LICENSE) 
    5076   !!---------------------------------------------------------------------- 
    5177CONTAINS 
    52  
    53 #else 
    54    !!---------------------------------------------------------------------- 
    55    !!   Default option                              shared memory computing 
    56    !!---------------------------------------------------------------------- 
    57    !!                routines setting the appropriate values 
    58    !!         on first and last row and column of the global domain 
    59    !!---------------------------------------------------------------------- 
    60    !!   lbc_lnk_sum_3d: compute sum over the halos on a 3D variable on ocean mesh 
    61    !!   lbc_lnk_sum_3d: compute sum over the halos on a 2D variable on ocean mesh 
    62    !!   lbc_lnk       : generic interface for lbc_lnk_3d and lbc_lnk_2d 
    63    !!   lbc_lnk_3d    : set the lateral boundary condition on a 3D variable on ocean mesh 
    64    !!   lbc_lnk_2d    : set the lateral boundary condition on a 2D variable on ocean mesh 
    65    !!---------------------------------------------------------------------- 
    66    USE dom_oce        ! ocean space and time domain  
    67    USE in_out_manager ! I/O manager 
    68    USE lbcnfd         ! north fold 
    69  
    70    IMPLICIT NONE 
    71    PRIVATE 
    72  
    73    INTERFACE lbc_lnk 
    74       MODULE PROCEDURE   lbc_lnk_2d      , lbc_lnk_3d      , lbc_lnk_4d 
    75    END INTERFACE 
    76    INTERFACE lbc_lnk_ptr 
    77       MODULE PROCEDURE   lbc_lnk_2d_ptr  , lbc_lnk_3d_ptr  , lbc_lnk_4d_ptr 
    78    END INTERFACE 
    79    INTERFACE lbc_lnk_multi 
    80       MODULE PROCEDURE   lbc_lnk_2d_multi, lbc_lnk_3d_multi, lbc_lnk_4d_multi 
    81    END INTERFACE 
    82    ! 
    83    INTERFACE lbc_lnk_icb 
    84       MODULE PROCEDURE lbc_lnk_2d_icb 
    85    END INTERFACE 
    86     
    87    PUBLIC   lbc_lnk       ! ocean/ice  lateral boundary conditions 
    88    PUBLIC   lbc_lnk_multi ! modified ocean/ice lateral boundary conditions 
    89    PUBLIC   lbc_lnk_icb   ! iceberg lateral boundary conditions 
    90     
    91    !!---------------------------------------------------------------------- 
    92    !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    93    !! $Id: lbclnk.F90 10425 2018-12-19 21:54:16Z smasson $ 
    94    !! Software governed by the CeCILL license (see ./LICENSE) 
    95    !!---------------------------------------------------------------------- 
    96 CONTAINS 
    97  
    98    !!====================================================================== 
    99    !!   Default option                           3D shared memory computing 
    100    !!====================================================================== 
    101    !!          routines setting land point, or east-west cyclic, 
    102    !!             or north-south cyclic, or north fold values 
    103    !!         on first and last row and column of the global domain 
    104    !!---------------------------------------------------------------------- 
    105  
    106    !!---------------------------------------------------------------------- 
    107    !!                   ***  routine lbc_lnk_(2,3,4)d  *** 
    108    !! 
    109    !!   * Argument : dummy argument use in lbc_lnk_... routines 
    110    !!                ptab   :   array or pointer of arrays on which the boundary condition is applied 
    111    !!                cd_nat :   nature of array grid-points 
    112    !!                psgn   :   sign used across the north fold boundary 
    113    !!                kfld   :   optional, number of pt3d arrays 
    114    !!                cd_mpp :   optional, fill the overlap area only 
    115    !!                pval   :   optional, background value (used at closed boundaries) 
    116    !!---------------------------------------------------------------------- 
    117    ! 
    118    !                       !==  2D array and array of 2D pointer  ==! 
    119    ! 
    120 #  define DIM_2d 
    121 #     define ROUTINE_LNK           lbc_lnk_2d 
    122 #     include "lbc_lnk_generic.h90" 
    123 #     undef ROUTINE_LNK 
    124 #     define MULTI 
    125 #     define ROUTINE_LNK           lbc_lnk_2d_ptr 
    126 #     include "lbc_lnk_generic.h90" 
    127 #     undef ROUTINE_LNK 
    128 #     undef MULTI 
    129 #  undef DIM_2d 
    130    ! 
    131    !                       !==  3D array and array of 3D pointer  ==! 
    132    ! 
    133 #  define DIM_3d 
    134 #     define ROUTINE_LNK           lbc_lnk_3d 
    135 #     include "lbc_lnk_generic.h90" 
    136 #     undef ROUTINE_LNK 
    137 #     define MULTI 
    138 #     define ROUTINE_LNK           lbc_lnk_3d_ptr 
    139 #     include "lbc_lnk_generic.h90" 
    140 #     undef ROUTINE_LNK 
    141 #     undef MULTI 
    142 #  undef DIM_3d 
    143    ! 
    144    !                       !==  4D array and array of 4D pointer  ==! 
    145    ! 
    146 #  define DIM_4d 
    147 #     define ROUTINE_LNK           lbc_lnk_4d 
    148 #     include "lbc_lnk_generic.h90" 
    149 #     undef ROUTINE_LNK 
    150 #     define MULTI 
    151 #     define ROUTINE_LNK           lbc_lnk_4d_ptr 
    152 #     include "lbc_lnk_generic.h90" 
    153 #     undef ROUTINE_LNK 
    154 #     undef MULTI 
    155 #  undef DIM_4d 
    156     
    157    !!====================================================================== 
    158    !!   identical routines in both C1D and shared memory computing 
    159    !!====================================================================== 
    160  
    161    !!---------------------------------------------------------------------- 
    162  
    163 !!gm  This routine should be removed with an optional halos size added in argument of generic routines 
    164  
    165    SUBROUTINE lbc_lnk_2d_icb( cdname, pt2d, cd_type, psgn, ki, kj ) 
    166       !!---------------------------------------------------------------------- 
    167       CHARACTER(len=*)        , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
    168       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d      ! 2D array on which the lbc is applied 
    169       CHARACTER(len=1)        , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points 
    170       REAL(wp)                , INTENT(in   ) ::   psgn      ! sign used across north fold  
    171       INTEGER                 , INTENT(in   ) ::   ki, kj    ! sizes of extra halo (not needed in non-mpp) 
    172       !!---------------------------------------------------------------------- 
    173       CALL lbc_lnk_2d( cdname, pt2d, cd_type, psgn ) 
    174    END SUBROUTINE lbc_lnk_2d_icb 
    175 !!gm end 
    176  
    177 #endif 
    178  
    179    !!====================================================================== 
    180    !!   identical routines in both distributed and shared memory computing 
    181    !!====================================================================== 
    18278 
    18379   !!---------------------------------------------------------------------- 
     
    20298   !!---------------------------------------------------------------------- 
    20399 
    204 #  define DIM_2d 
    205 #     define ROUTINE_MULTI          lbc_lnk_2d_multi 
    206 #     define ROUTINE_LOAD           load_ptr_2d 
    207 #     include "lbc_lnk_multi_generic.h90" 
    208 #     undef ROUTINE_MULTI 
    209 #     undef ROUTINE_LOAD 
    210 #  undef DIM_2d 
    211  
    212  
    213 #  define DIM_3d 
    214 #     define ROUTINE_MULTI          lbc_lnk_3d_multi 
    215 #     define ROUTINE_LOAD           load_ptr_3d 
    216 #     include "lbc_lnk_multi_generic.h90" 
    217 #     undef ROUTINE_MULTI 
    218 #     undef ROUTINE_LOAD 
    219 #  undef DIM_3d 
    220  
    221  
    222 #  define DIM_4d 
    223 #     define ROUTINE_MULTI          lbc_lnk_4d_multi 
    224 #     define ROUTINE_LOAD           load_ptr_4d 
    225 #     include "lbc_lnk_multi_generic.h90" 
    226 #     undef ROUTINE_MULTI 
    227 #     undef ROUTINE_LOAD 
     100   !! 
     101   !!   ----   SINGLE PRECISION VERSIONS 
     102   !! 
     103#  define SINGLE_PRECISION 
     104#  define DIM_2d 
     105#     define ROUTINE_LOAD           load_ptr_2d_sp 
     106#     define ROUTINE_MULTI          lbc_lnk_2d_multi_sp 
     107#     include "lbc_lnk_multi_generic.h90" 
     108#     undef ROUTINE_MULTI 
     109#     undef ROUTINE_LOAD 
     110#  undef DIM_2d 
     111 
     112#  define DIM_3d 
     113#     define ROUTINE_LOAD           load_ptr_3d_sp 
     114#     define ROUTINE_MULTI          lbc_lnk_3d_multi_sp 
     115#     include "lbc_lnk_multi_generic.h90" 
     116#     undef ROUTINE_MULTI 
     117#     undef ROUTINE_LOAD 
     118#  undef DIM_3d 
     119 
     120#  define DIM_4d 
     121#     define ROUTINE_LOAD           load_ptr_4d_sp 
     122#     define ROUTINE_MULTI          lbc_lnk_4d_multi_sp 
     123#     include "lbc_lnk_multi_generic.h90" 
     124#     undef ROUTINE_MULTI 
     125#     undef ROUTINE_LOAD 
     126#  undef DIM_4d 
     127#  undef SINGLE_PRECISION 
     128   !! 
     129   !!   ----   DOUBLE PRECISION VERSIONS 
     130   !! 
     131 
     132#  define DIM_2d 
     133#     define ROUTINE_LOAD           load_ptr_2d_dp 
     134#     define ROUTINE_MULTI          lbc_lnk_2d_multi_dp 
     135#     include "lbc_lnk_multi_generic.h90" 
     136#     undef ROUTINE_MULTI 
     137#     undef ROUTINE_LOAD 
     138#  undef DIM_2d 
     139 
     140#  define DIM_3d 
     141#     define ROUTINE_LOAD           load_ptr_3d_dp 
     142#     define ROUTINE_MULTI          lbc_lnk_3d_multi_dp 
     143#     include "lbc_lnk_multi_generic.h90" 
     144#     undef ROUTINE_MULTI 
     145#     undef ROUTINE_LOAD 
     146#  undef DIM_3d 
     147 
     148#  define DIM_4d 
     149#     define ROUTINE_LOAD           load_ptr_4d_dp 
     150#     define ROUTINE_MULTI          lbc_lnk_4d_multi_dp 
     151#     include "lbc_lnk_multi_generic.h90" 
     152#     undef ROUTINE_MULTI 
     153#     undef ROUTINE_LOAD 
     154#  undef DIM_4d 
     155 
     156   !!---------------------------------------------------------------------- 
     157   !!                   ***  routine mpp_lnk_(2,3,4)d  *** 
     158   !! 
     159   !!   * Argument : dummy argument use in mpp_lnk_... routines 
     160   !!                ptab      :   array or pointer of arrays on which the boundary condition is applied 
     161   !!                cd_nat    :   nature of array grid-points 
     162   !!                psgn      :   sign used across the north fold boundary 
     163   !!                kfld      :   optional, number of pt3d arrays 
     164   !!                kfillmode :   optional, method to be use to fill the halos (see jpfill* variables) 
     165   !!                pfillval  :   optional, background value (used with jpfillcopy) 
     166   !!---------------------------------------------------------------------- 
     167   ! 
     168   !                       !==  2D array and array of 2D pointer  ==! 
     169   ! 
     170   !! 
     171   !!   ----   SINGLE PRECISION VERSIONS 
     172   !! 
     173# define SINGLE_PRECISION 
     174#  define DIM_2d 
     175#     define ROUTINE_LNK           mpp_lnk_2d_sp 
     176#     include "mpp_lnk_generic.h90" 
     177#     undef ROUTINE_LNK 
     178#     define MULTI 
     179#     define ROUTINE_LNK           mpp_lnk_2d_ptr_sp 
     180#     include "mpp_lnk_generic.h90" 
     181#     undef ROUTINE_LNK 
     182#     undef MULTI 
     183#  undef DIM_2d 
     184   ! 
     185   !                       !==  3D array and array of 3D pointer  ==! 
     186   ! 
     187#  define DIM_3d 
     188#     define ROUTINE_LNK           mpp_lnk_3d_sp 
     189#     include "mpp_lnk_generic.h90" 
     190#     undef ROUTINE_LNK 
     191#     define MULTI 
     192#     define ROUTINE_LNK           mpp_lnk_3d_ptr_sp 
     193#     include "mpp_lnk_generic.h90" 
     194#     undef ROUTINE_LNK 
     195#     undef MULTI 
     196#  undef DIM_3d 
     197   ! 
     198   !                       !==  4D array and array of 4D pointer  ==! 
     199   ! 
     200#  define DIM_4d 
     201#     define ROUTINE_LNK           mpp_lnk_4d_sp 
     202#     include "mpp_lnk_generic.h90" 
     203#     undef ROUTINE_LNK 
     204#     define MULTI 
     205#     define ROUTINE_LNK           mpp_lnk_4d_ptr_sp 
     206#     include "mpp_lnk_generic.h90" 
     207#     undef ROUTINE_LNK 
     208#     undef MULTI 
     209#  undef DIM_4d 
     210# undef SINGLE_PRECISION 
     211 
     212   !! 
     213   !!   ----   DOUBLE PRECISION VERSIONS 
     214   !! 
     215#  define DIM_2d 
     216#     define ROUTINE_LNK           mpp_lnk_2d_dp 
     217#     include "mpp_lnk_generic.h90" 
     218#     undef ROUTINE_LNK 
     219#     define MULTI 
     220#     define ROUTINE_LNK           mpp_lnk_2d_ptr_dp 
     221#     include "mpp_lnk_generic.h90" 
     222#     undef ROUTINE_LNK 
     223#     undef MULTI 
     224#  undef DIM_2d 
     225   ! 
     226   !                       !==  3D array and array of 3D pointer  ==! 
     227   ! 
     228#  define DIM_3d 
     229#     define ROUTINE_LNK           mpp_lnk_3d_dp 
     230#     include "mpp_lnk_generic.h90" 
     231#     undef ROUTINE_LNK 
     232#     define MULTI 
     233#     define ROUTINE_LNK           mpp_lnk_3d_ptr_dp 
     234#     include "mpp_lnk_generic.h90" 
     235#     undef ROUTINE_LNK 
     236#     undef MULTI 
     237#  undef DIM_3d 
     238   ! 
     239   !                       !==  4D array and array of 4D pointer  ==! 
     240   ! 
     241#  define DIM_4d 
     242#     define ROUTINE_LNK           mpp_lnk_4d_dp 
     243#     include "mpp_lnk_generic.h90" 
     244#     undef ROUTINE_LNK 
     245#     define MULTI 
     246#     define ROUTINE_LNK           mpp_lnk_4d_ptr_dp 
     247#     include "mpp_lnk_generic.h90" 
     248#     undef ROUTINE_LNK 
     249#     undef MULTI 
     250#  undef DIM_4d 
     251 
     252 
     253   !!---------------------------------------------------------------------- 
     254   !!                   ***  routine mpp_nfd_(2,3,4)d  *** 
     255   !! 
     256   !!   * Argument : dummy argument use in mpp_nfd_... routines 
     257   !!                ptab      :   array or pointer of arrays on which the boundary condition is applied 
     258   !!                cd_nat    :   nature of array grid-points 
     259   !!                psgn      :   sign used across the north fold boundary 
     260   !!                kfld      :   optional, number of pt3d arrays 
     261   !!                kfillmode :   optional, method to be use to fill the halos (see jpfill* variables) 
     262   !!                pfillval  :   optional, background value (used with jpfillcopy) 
     263   !!---------------------------------------------------------------------- 
     264   ! 
     265   !                       !==  2D array and array of 2D pointer  ==! 
     266   ! 
     267   !! 
     268   !!   ----   SINGLE PRECISION VERSIONS 
     269   !! 
     270#  define SINGLE_PRECISION 
     271#  define DIM_2d 
     272#     define ROUTINE_NFD           mpp_nfd_2d_sp 
     273#     include "mpp_nfd_generic.h90" 
     274#     undef ROUTINE_NFD 
     275#     define MULTI 
     276#     define ROUTINE_NFD           mpp_nfd_2d_ptr_sp 
     277#     include "mpp_nfd_generic.h90" 
     278#     undef ROUTINE_NFD 
     279#     undef MULTI 
     280#  undef DIM_2d 
     281   ! 
     282   !                       !==  3D array and array of 3D pointer  ==! 
     283   ! 
     284#  define DIM_3d 
     285#     define ROUTINE_NFD           mpp_nfd_3d_sp 
     286#     include "mpp_nfd_generic.h90" 
     287#     undef ROUTINE_NFD 
     288#     define MULTI 
     289#     define ROUTINE_NFD           mpp_nfd_3d_ptr_sp 
     290#     include "mpp_nfd_generic.h90" 
     291#     undef ROUTINE_NFD 
     292#     undef MULTI 
     293#  undef DIM_3d 
     294   ! 
     295   !                       !==  4D array and array of 4D pointer  ==! 
     296   ! 
     297#  define DIM_4d 
     298#     define ROUTINE_NFD           mpp_nfd_4d_sp 
     299#     include "mpp_nfd_generic.h90" 
     300#     undef ROUTINE_NFD 
     301#     define MULTI 
     302#     define ROUTINE_NFD           mpp_nfd_4d_ptr_sp 
     303#     include "mpp_nfd_generic.h90" 
     304#     undef ROUTINE_NFD 
     305#     undef MULTI 
     306#  undef DIM_4d 
     307#  undef SINGLE_PRECISION 
     308 
     309   !! 
     310   !!   ----   DOUBLE PRECISION VERSIONS 
     311   !! 
     312#  define DIM_2d 
     313#     define ROUTINE_NFD           mpp_nfd_2d_dp 
     314#     include "mpp_nfd_generic.h90" 
     315#     undef ROUTINE_NFD 
     316#     define MULTI 
     317#     define ROUTINE_NFD           mpp_nfd_2d_ptr_dp 
     318#     include "mpp_nfd_generic.h90" 
     319#     undef ROUTINE_NFD 
     320#     undef MULTI 
     321#  undef DIM_2d 
     322   ! 
     323   !                       !==  3D array and array of 3D pointer  ==! 
     324   ! 
     325#  define DIM_3d 
     326#     define ROUTINE_NFD           mpp_nfd_3d_dp 
     327#     include "mpp_nfd_generic.h90" 
     328#     undef ROUTINE_NFD 
     329#     define MULTI 
     330#     define ROUTINE_NFD           mpp_nfd_3d_ptr_dp 
     331#     include "mpp_nfd_generic.h90" 
     332#     undef ROUTINE_NFD 
     333#     undef MULTI 
     334#  undef DIM_3d 
     335   ! 
     336   !                       !==  4D array and array of 4D pointer  ==! 
     337   ! 
     338#  define DIM_4d 
     339#     define ROUTINE_NFD           mpp_nfd_4d_dp 
     340#     include "mpp_nfd_generic.h90" 
     341#     undef ROUTINE_NFD 
     342#     define MULTI 
     343#     define ROUTINE_NFD           mpp_nfd_4d_ptr_dp 
     344#     include "mpp_nfd_generic.h90" 
     345#     undef ROUTINE_NFD 
     346#     undef MULTI 
    228347#  undef DIM_4d 
    229348 
    230349   !!====================================================================== 
     350 
     351 
     352   !!====================================================================== 
     353     !!--------------------------------------------------------------------- 
     354      !!                   ***  routine mpp_lbc_north_icb  *** 
     355      !! 
     356      !! ** Purpose :   Ensure proper north fold horizontal bondary condition 
     357      !!              in mpp configuration in case of jpn1 > 1 and for 2d 
     358      !!              array with outer extra halo 
     359      !! 
     360      !! ** Method  :   North fold condition and mpp with more than one proc 
     361      !!              in i-direction require a specific treatment. We gather 
     362      !!              the 4+kextj northern lines of the global domain on 1 
     363      !!              processor and apply lbc north-fold on this sub array. 
     364      !!              Then we scatter the north fold array back to the processors. 
     365      !!              This routine accounts for an extra halo with icebergs 
     366      !!              and assumes ghost rows and columns have been suppressed. 
     367      !! 
     368      !!---------------------------------------------------------------------- 
     369#     define SINGLE_PRECISION 
     370#     define ROUTINE_LNK           mpp_lbc_north_icb_sp 
     371#     include "mpp_lbc_north_icb_generic.h90" 
     372#     undef ROUTINE_LNK 
     373#     undef SINGLE_PRECISION 
     374#     define ROUTINE_LNK           mpp_lbc_north_icb_dp 
     375#     include "mpp_lbc_north_icb_generic.h90" 
     376#     undef ROUTINE_LNK 
     377  
     378 
     379      !!---------------------------------------------------------------------- 
     380      !!                  ***  routine mpp_lnk_2d_icb  *** 
     381      !! 
     382      !! ** Purpose :   Message passing management for 2d array (with extra halo for icebergs) 
     383      !!                This routine receives a (1-kexti:jpi+kexti,1-kexti:jpj+kextj) 
     384      !!                array (usually (0:jpi+1, 0:jpj+1)) from lbc_lnk_icb calls. 
     385      !! 
     386      !! ** Method  :   Use mppsend and mpprecv function for passing mask 
     387      !!      between processors following neighboring subdomains. 
     388      !!            domain parameters 
     389      !!                    jpi    : first dimension of the local subdomain 
     390      !!                    jpj    : second dimension of the local subdomain 
     391      !!                    kexti  : number of columns for extra outer halo 
     392      !!                    kextj  : number of rows for extra outer halo 
     393      !!                    nbondi : mark for "east-west local boundary" 
     394      !!                    nbondj : mark for "north-south local boundary" 
     395      !!                    noea   : number for local neighboring processors 
     396      !!                    nowe   : number for local neighboring processors 
     397      !!                    noso   : number for local neighboring processors 
     398      !!                    nono   : number for local neighboring processors 
     399      !!---------------------------------------------------------------------- 
     400 
     401#     define SINGLE_PRECISION 
     402#     define ROUTINE_LNK           mpp_lnk_2d_icb_sp 
     403#     include "mpp_lnk_icb_generic.h90" 
     404#     undef ROUTINE_LNK 
     405#     undef SINGLE_PRECISION 
     406#     define ROUTINE_LNK           mpp_lnk_2d_icb_dp 
     407#     include "mpp_lnk_icb_generic.h90" 
     408#     undef ROUTINE_LNK 
     409   
    231410END MODULE lbclnk 
    232411 
  • utils/tools/DOMAINcfg/src/lbcnfd.F90

    r12414 r14623  
    2020   USE dom_oce        ! ocean space and time domain  
    2121   USE in_out_manager ! I/O manager 
     22   USE lib_mpp        ! MPP library 
    2223 
    2324   IMPLICIT NONE 
     
    2526 
    2627   INTERFACE lbc_nfd 
    27       MODULE PROCEDURE   lbc_nfd_2d    , lbc_nfd_3d    , lbc_nfd_4d 
    28       MODULE PROCEDURE   lbc_nfd_2d_ptr, lbc_nfd_3d_ptr, lbc_nfd_4d_ptr 
    29       MODULE PROCEDURE   lbc_nfd_2d_ext 
     28      MODULE PROCEDURE   lbc_nfd_2d_sp    , lbc_nfd_3d_sp    , lbc_nfd_4d_sp 
     29      MODULE PROCEDURE   lbc_nfd_2d_ptr_sp, lbc_nfd_3d_ptr_sp, lbc_nfd_4d_ptr_sp 
     30      MODULE PROCEDURE   lbc_nfd_2d_ext_sp 
     31      MODULE PROCEDURE   lbc_nfd_2d_dp    , lbc_nfd_3d_dp    , lbc_nfd_4d_dp 
     32      MODULE PROCEDURE   lbc_nfd_2d_ptr_dp, lbc_nfd_3d_ptr_dp, lbc_nfd_4d_ptr_dp 
     33      MODULE PROCEDURE   lbc_nfd_2d_ext_dp 
    3034   END INTERFACE 
    3135   ! 
    3236   INTERFACE lbc_nfd_nogather 
    3337!                        ! Currently only 4d array version is needed 
    34      MODULE PROCEDURE   lbc_nfd_nogather_2d    , lbc_nfd_nogather_3d 
    35      MODULE PROCEDURE   lbc_nfd_nogather_4d 
    36      MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr, lbc_nfd_nogather_3d_ptr 
     38     MODULE PROCEDURE   lbc_nfd_nogather_2d_sp    , lbc_nfd_nogather_3d_sp 
     39     MODULE PROCEDURE   lbc_nfd_nogather_4d_sp 
     40     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr_sp, lbc_nfd_nogather_3d_ptr_sp 
     41     MODULE PROCEDURE   lbc_nfd_nogather_2d_dp    , lbc_nfd_nogather_3d_dp 
     42     MODULE PROCEDURE   lbc_nfd_nogather_4d_dp 
     43     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr_dp, lbc_nfd_nogather_3d_ptr_dp 
    3744!     MODULE PROCEDURE   lbc_nfd_nogather_4d_ptr 
    3845   END INTERFACE 
    3946 
    40    TYPE, PUBLIC ::   PTR_2D   !: array of 2D pointers (also used in lib_mpp) 
    41       REAL(wp), DIMENSION (:,:)    , POINTER ::   pt2d 
    42    END TYPE PTR_2D 
    43    TYPE, PUBLIC ::   PTR_3D   !: array of 3D pointers (also used in lib_mpp) 
    44       REAL(wp), DIMENSION (:,:,:)  , POINTER ::   pt3d 
    45    END TYPE PTR_3D 
    46    TYPE, PUBLIC ::   PTR_4D   !: array of 4D pointers (also used in lib_mpp) 
    47       REAL(wp), DIMENSION (:,:,:,:), POINTER ::   pt4d 
    48    END TYPE PTR_4D 
     47   TYPE, PUBLIC ::   PTR_2D_dp   !: array of 2D pointers (also used in lib_mpp) 
     48      REAL(dp), DIMENSION (:,:)    , POINTER ::   pt2d 
     49   END TYPE PTR_2D_dp 
     50   TYPE, PUBLIC ::   PTR_3D_dp   !: array of 3D pointers (also used in lib_mpp) 
     51      REAL(dp), DIMENSION (:,:,:)  , POINTER ::   pt3d 
     52   END TYPE PTR_3D_dp 
     53   TYPE, PUBLIC ::   PTR_4D_dp   !: array of 4D pointers (also used in lib_mpp) 
     54      REAL(dp), DIMENSION (:,:,:,:), POINTER ::   pt4d 
     55   END TYPE PTR_4D_dp 
     56 
     57   TYPE, PUBLIC ::   PTR_2D_sp   !: array of 2D pointers (also used in lib_mpp) 
     58      REAL(sp), DIMENSION (:,:)    , POINTER ::   pt2d 
     59   END TYPE PTR_2D_sp 
     60   TYPE, PUBLIC ::   PTR_3D_sp   !: array of 3D pointers (also used in lib_mpp) 
     61      REAL(sp), DIMENSION (:,:,:)  , POINTER ::   pt3d 
     62   END TYPE PTR_3D_sp 
     63   TYPE, PUBLIC ::   PTR_4D_sp   !: array of 4D pointers (also used in lib_mpp) 
     64      REAL(sp), DIMENSION (:,:,:,:), POINTER ::   pt4d 
     65   END TYPE PTR_4D_sp 
     66 
    4967 
    5068   PUBLIC   lbc_nfd            ! north fold conditions 
     
    5270 
    5371   INTEGER, PUBLIC, PARAMETER            ::   jpmaxngh = 3               !: 
    54    INTEGER, PUBLIC                       ::   nsndto, nfsloop, nfeloop   !: 
     72   INTEGER, PUBLIC                       ::   nsndto                     !: 
    5573   INTEGER, PUBLIC, DIMENSION (jpmaxngh) ::   isendto                    !: processes to which communicate 
     74   INTEGER, PUBLIC                       ::   ijpj 
    5675 
    5776   !!---------------------------------------------------------------------- 
    5877   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    59    !! $Id: lbcnfd.F90 10425 2018-12-19 21:54:16Z smasson $ 
     78   !! $Id: lbcnfd.F90 13286 2020-07-09 15:48:29Z smasson $ 
    6079   !! Software governed by the CeCILL license (see ./LICENSE) 
    6180   !!---------------------------------------------------------------------- 
     
    7493   !!---------------------------------------------------------------------- 
    7594   ! 
    76    !                       !==  2D array and array of 2D pointer  ==! 
    77    ! 
    78 #  define DIM_2d 
    79 #     define ROUTINE_NFD           lbc_nfd_2d 
    80 #     include "lbc_nfd_generic.h90" 
    81 #     undef ROUTINE_NFD 
    82 #     define MULTI 
    83 #     define ROUTINE_NFD           lbc_nfd_2d_ptr 
     95   !                       !==  SINGLE PRECISION VERSIONS 
     96   ! 
     97   ! 
     98   !                       !==  2D array and array of 2D pointer  ==! 
     99   ! 
     100#  define SINGLE_PRECISION 
     101#  define DIM_2d 
     102#     define ROUTINE_NFD           lbc_nfd_2d_sp 
     103#     include "lbc_nfd_generic.h90" 
     104#     undef ROUTINE_NFD 
     105#     define MULTI 
     106#     define ROUTINE_NFD           lbc_nfd_2d_ptr_sp 
    84107#     include "lbc_nfd_generic.h90" 
    85108#     undef ROUTINE_NFD 
     
    90113   ! 
    91114#  define DIM_2d 
    92 #     define ROUTINE_NFD           lbc_nfd_2d_ext 
     115#     define ROUTINE_NFD           lbc_nfd_2d_ext_sp 
    93116#     include "lbc_nfd_ext_generic.h90" 
    94117#     undef ROUTINE_NFD 
     
    98121   ! 
    99122#  define DIM_3d 
    100 #     define ROUTINE_NFD           lbc_nfd_3d 
    101 #     include "lbc_nfd_generic.h90" 
    102 #     undef ROUTINE_NFD 
    103 #     define MULTI 
    104 #     define ROUTINE_NFD           lbc_nfd_3d_ptr 
    105 #     include "lbc_nfd_generic.h90" 
    106 #     undef ROUTINE_NFD 
    107 #     undef MULTI 
    108 #  undef DIM_3d 
    109    ! 
    110    !                       !==  4D array and array of 4D pointer  ==! 
    111    ! 
    112 #  define DIM_4d 
    113 #     define ROUTINE_NFD           lbc_nfd_4d 
    114 #     include "lbc_nfd_generic.h90" 
    115 #     undef ROUTINE_NFD 
    116 #     define MULTI 
    117 #     define ROUTINE_NFD           lbc_nfd_4d_ptr 
     123#     define ROUTINE_NFD           lbc_nfd_3d_sp 
     124#     include "lbc_nfd_generic.h90" 
     125#     undef ROUTINE_NFD 
     126#     define MULTI 
     127#     define ROUTINE_NFD           lbc_nfd_3d_ptr_sp 
     128#     include "lbc_nfd_generic.h90" 
     129#     undef ROUTINE_NFD 
     130#     undef MULTI 
     131#  undef DIM_3d 
     132   ! 
     133   !                       !==  4D array and array of 4D pointer  ==! 
     134   ! 
     135#  define DIM_4d 
     136#     define ROUTINE_NFD           lbc_nfd_4d_sp 
     137#     include "lbc_nfd_generic.h90" 
     138#     undef ROUTINE_NFD 
     139#     define MULTI 
     140#     define ROUTINE_NFD           lbc_nfd_4d_ptr_sp 
    118141#     include "lbc_nfd_generic.h90" 
    119142#     undef ROUTINE_NFD 
     
    126149   ! 
    127150#  define DIM_2d 
    128 #     define ROUTINE_NFD           lbc_nfd_nogather_2d 
    129 #     include "lbc_nfd_nogather_generic.h90" 
    130 #     undef ROUTINE_NFD 
    131 #     define MULTI 
    132 #     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr 
    133 #     include "lbc_nfd_nogather_generic.h90" 
    134 #     undef ROUTINE_NFD 
    135 #     undef MULTI 
    136 #  undef DIM_2d 
    137    ! 
    138    !                       !==  3D array and array of 3D pointer  ==! 
    139    ! 
    140 #  define DIM_3d 
    141 #     define ROUTINE_NFD           lbc_nfd_nogather_3d 
    142 #     include "lbc_nfd_nogather_generic.h90" 
    143 #     undef ROUTINE_NFD 
    144 #     define MULTI 
    145 #     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr 
    146 #     include "lbc_nfd_nogather_generic.h90" 
    147 #     undef ROUTINE_NFD 
    148 #     undef MULTI 
    149 #  undef DIM_3d 
    150    ! 
    151    !                       !==  4D array and array of 4D pointer  ==! 
    152    ! 
    153 #  define DIM_4d 
    154 #     define ROUTINE_NFD           lbc_nfd_nogather_4d 
     151#     define ROUTINE_NFD           lbc_nfd_nogather_2d_sp 
     152#     include "lbc_nfd_nogather_generic.h90" 
     153#     undef ROUTINE_NFD 
     154#     define MULTI 
     155#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr_sp 
     156#     include "lbc_nfd_nogather_generic.h90" 
     157#     undef ROUTINE_NFD 
     158#     undef MULTI 
     159#  undef DIM_2d 
     160   ! 
     161   !                       !==  3D array and array of 3D pointer  ==! 
     162   ! 
     163#  define DIM_3d 
     164#     define ROUTINE_NFD           lbc_nfd_nogather_3d_sp 
     165#     include "lbc_nfd_nogather_generic.h90" 
     166#     undef ROUTINE_NFD 
     167#     define MULTI 
     168#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr_sp 
     169#     include "lbc_nfd_nogather_generic.h90" 
     170#     undef ROUTINE_NFD 
     171#     undef MULTI 
     172#  undef DIM_3d 
     173   ! 
     174   !                       !==  4D array and array of 4D pointer  ==! 
     175   ! 
     176#  define DIM_4d 
     177#     define ROUTINE_NFD           lbc_nfd_nogather_4d_sp 
    155178#     include "lbc_nfd_nogather_generic.h90" 
    156179#     undef ROUTINE_NFD 
     
    161184!#     undef MULTI 
    162185#  undef DIM_4d 
    163  
    164    !!---------------------------------------------------------------------- 
     186#  undef SINGLE_PRECISION 
     187 
     188   !!---------------------------------------------------------------------- 
     189   ! 
     190   !                       !==  DOUBLE PRECISION VERSIONS 
     191   ! 
     192   ! 
     193   !                       !==  2D array and array of 2D pointer  ==! 
     194   ! 
     195#  define DIM_2d 
     196#     define ROUTINE_NFD           lbc_nfd_2d_dp 
     197#     include "lbc_nfd_generic.h90" 
     198#     undef ROUTINE_NFD 
     199#     define MULTI 
     200#     define ROUTINE_NFD           lbc_nfd_2d_ptr_dp 
     201#     include "lbc_nfd_generic.h90" 
     202#     undef ROUTINE_NFD 
     203#     undef MULTI 
     204#  undef DIM_2d 
     205   ! 
     206   !                       !==  2D array with extra haloes  ==! 
     207   ! 
     208#  define DIM_2d 
     209#     define ROUTINE_NFD           lbc_nfd_2d_ext_dp 
     210#     include "lbc_nfd_ext_generic.h90" 
     211#     undef ROUTINE_NFD 
     212#  undef DIM_2d 
     213   ! 
     214   !                       !==  3D array and array of 3D pointer  ==! 
     215   ! 
     216#  define DIM_3d 
     217#     define ROUTINE_NFD           lbc_nfd_3d_dp 
     218#     include "lbc_nfd_generic.h90" 
     219#     undef ROUTINE_NFD 
     220#     define MULTI 
     221#     define ROUTINE_NFD           lbc_nfd_3d_ptr_dp 
     222#     include "lbc_nfd_generic.h90" 
     223#     undef ROUTINE_NFD 
     224#     undef MULTI 
     225#  undef DIM_3d 
     226   ! 
     227   !                       !==  4D array and array of 4D pointer  ==! 
     228   ! 
     229#  define DIM_4d 
     230#     define ROUTINE_NFD           lbc_nfd_4d_dp 
     231#     include "lbc_nfd_generic.h90" 
     232#     undef ROUTINE_NFD 
     233#     define MULTI 
     234#     define ROUTINE_NFD           lbc_nfd_4d_ptr_dp 
     235#     include "lbc_nfd_generic.h90" 
     236#     undef ROUTINE_NFD 
     237#     undef MULTI 
     238#  undef DIM_4d 
     239   ! 
     240   !  lbc_nfd_nogather routines 
     241   ! 
     242   !                       !==  2D array and array of 2D pointer  ==! 
     243   ! 
     244#  define DIM_2d 
     245#     define ROUTINE_NFD           lbc_nfd_nogather_2d_dp 
     246#     include "lbc_nfd_nogather_generic.h90" 
     247#     undef ROUTINE_NFD 
     248#     define MULTI 
     249#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr_dp 
     250#     include "lbc_nfd_nogather_generic.h90" 
     251#     undef ROUTINE_NFD 
     252#     undef MULTI 
     253#  undef DIM_2d 
     254   ! 
     255   !                       !==  3D array and array of 3D pointer  ==! 
     256   ! 
     257#  define DIM_3d 
     258#     define ROUTINE_NFD           lbc_nfd_nogather_3d_dp 
     259#     include "lbc_nfd_nogather_generic.h90" 
     260#     undef ROUTINE_NFD 
     261#     define MULTI 
     262#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr_dp 
     263#     include "lbc_nfd_nogather_generic.h90" 
     264#     undef ROUTINE_NFD 
     265#     undef MULTI 
     266#  undef DIM_3d 
     267   ! 
     268   !                       !==  4D array and array of 4D pointer  ==! 
     269   ! 
     270#  define DIM_4d 
     271#     define ROUTINE_NFD           lbc_nfd_nogather_4d_dp 
     272#     include "lbc_nfd_nogather_generic.h90" 
     273#     undef ROUTINE_NFD 
     274!#     define MULTI 
     275!#     define ROUTINE_NFD           lbc_nfd_nogather_4d_ptr 
     276!#     include "lbc_nfd_nogather_generic.h90" 
     277!#     undef ROUTINE_NFD 
     278!#     undef MULTI 
     279#  undef DIM_4d 
     280 
     281   !!---------------------------------------------------------------------- 
     282 
    165283 
    166284 
  • utils/tools/DOMAINcfg/src/lib_fortran.F90

    r12414 r14623  
    6363#endif 
    6464 
     65   !! * Substitutions 
     66#  include "do_loop_substitute.h90" 
    6567   !!---------------------------------------------------------------------- 
    6668   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    67    !! $Id: lib_fortran.F90 10425 2018-12-19 21:54:16Z smasson $ 
     69   !! $Id: lib_fortran.F90 13295 2020-07-10 18:24:21Z acc $ 
    6870   !! Software governed by the CeCILL license (see ./LICENSE) 
    6971   !!---------------------------------------------------------------------- 
     
    141143      !!---------------------------------------------------------------------- 
    142144      REAL(wp),  INTENT(in   ) ::   ptab(:,:) ! array on which operation is applied 
    143       COMPLEX(wp)              ::  local_sum_2d 
    144       ! 
    145       !!----------------------------------------------------------------------- 
    146       ! 
    147       COMPLEX(wp)::   ctmp 
     145      COMPLEX(dp)              ::  local_sum_2d 
     146      ! 
     147      !!----------------------------------------------------------------------- 
     148      ! 
     149      COMPLEX(dp)::   ctmp 
    148150      REAL(wp)   ::   ztmp 
    149151      INTEGER    ::   ji, jj    ! dummy loop indices 
     
    159161         DO ji = 1, ipi 
    160162            ztmp =  ptab(ji,jj) * tmask_i(ji,jj) 
    161             CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp ) 
     163            CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp ) 
    162164         END DO 
    163165      END DO 
     
    170172      !!---------------------------------------------------------------------- 
    171173      REAL(wp),  INTENT(in   ) ::   ptab(:,:,:) ! array on which operation is applied 
    172       COMPLEX(wp)              ::  local_sum_3d 
    173       ! 
    174       !!----------------------------------------------------------------------- 
    175       ! 
    176       COMPLEX(wp)::   ctmp 
     174      COMPLEX(dp)              ::  local_sum_3d 
     175      ! 
     176      !!----------------------------------------------------------------------- 
     177      ! 
     178      COMPLEX(dp)::   ctmp 
    177179      REAL(wp)   ::   ztmp 
    178180      INTEGER    ::   ji, jj, jk   ! dummy loop indices 
     
    190192          DO ji = 1, ipi 
    191193             ztmp =  ptab(ji,jj,jk) * tmask_i(ji,jj) 
    192              CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp ) 
     194             CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp ) 
    193195          END DO 
    194196        END DO 
     
    215217      IF( SIZE(p2d,2) /= jpj ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_2d, the second dimension is not equal to jpj' )  
    216218      ! 
    217       DO jj = 1, jpj 
    218          DO ji = 1, jpi  
     219      DO_2D( 1, 1, 1, 1 ) 
     220         IF( MOD(mig(ji), 3) == 1 .AND. MOD(mjg(jj), 3) == 1 ) THEN   ! bottom left corber of a 3x3 box 
     221            ji2 = MIN(mig(ji)+2, jpiglo) - nimpp + 1                  ! right position of the box 
     222            jj2 = MIN(mjg(jj)+2, jpjglo) - njmpp + 1                  ! upper position of the box 
     223            IF( ji2 <= jpi .AND. jj2 <= jpj ) THEN                    ! the box is fully included in the local mpi domain 
     224               p2d(ji:ji2,jj:jj2) = SUM(p2d(ji:ji2,jj:jj2)) 
     225            ENDIF 
     226         ENDIF 
     227      END_2D 
     228      CALL lbc_lnk( 'lib_fortran', p2d, 'T', 1.0_wp ) 
     229      IF( nbondi /= -1 ) THEN 
     230         IF( MOD(mig(    1), 3) == 1 )   p2d(    1,:) = p2d(    2,:) 
     231         IF( MOD(mig(    1), 3) == 2 )   p2d(    2,:) = p2d(    1,:) 
     232      ENDIF 
     233      IF( nbondi /=  1 ) THEN 
     234         IF( MOD(mig(jpi-2), 3) == 1 )   p2d(  jpi,:) = p2d(jpi-1,:) 
     235         IF( MOD(mig(jpi-2), 3) == 0 )   p2d(jpi-1,:) = p2d(  jpi,:) 
     236      ENDIF 
     237      IF( nbondj /= -1 ) THEN 
     238         IF( MOD(mjg(    1), 3) == 1 )   p2d(:,    1) = p2d(:,    2) 
     239         IF( MOD(mjg(    1), 3) == 2 )   p2d(:,    2) = p2d(:,    1) 
     240      ENDIF 
     241      IF( nbondj /=  1 ) THEN 
     242         IF( MOD(mjg(jpj-2), 3) == 1 )   p2d(:,  jpj) = p2d(:,jpj-1) 
     243         IF( MOD(mjg(jpj-2), 3) == 0 )   p2d(:,jpj-1) = p2d(:,  jpj) 
     244      ENDIF 
     245      CALL lbc_lnk( 'lib_fortran', p2d, 'T', 1.0_wp ) 
     246 
     247   END SUBROUTINE sum3x3_2d 
     248 
     249   SUBROUTINE sum3x3_3d( p3d ) 
     250      !!----------------------------------------------------------------------- 
     251      !!                  ***  routine sum3x3_3d  *** 
     252      !! 
     253      !! ** Purpose : sum over 3x3 boxes 
     254      !!---------------------------------------------------------------------- 
     255      REAL(wp), DIMENSION (:,:,:), INTENT(inout) ::   p3d 
     256      ! 
     257      INTEGER ::   ji, ji2, jj, jj2, jn     ! dummy loop indices 
     258      INTEGER ::   ipn                      ! Third dimension size 
     259      !!---------------------------------------------------------------------- 
     260      ! 
     261      IF( SIZE(p3d,1) /= jpi ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_3d, the first dimension is not equal to jpi' )  
     262      IF( SIZE(p3d,2) /= jpj ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_3d, the second dimension is not equal to jpj' )  
     263      ipn = SIZE(p3d,3) 
     264      ! 
     265      DO jn = 1, ipn 
     266         DO_2D( 1, 1, 1, 1 ) 
    219267            IF( MOD(mig(ji), 3) == 1 .AND. MOD(mjg(jj), 3) == 1 ) THEN   ! bottom left corber of a 3x3 box 
    220268               ji2 = MIN(mig(ji)+2, jpiglo) - nimpp + 1                  ! right position of the box 
    221269               jj2 = MIN(mjg(jj)+2, jpjglo) - njmpp + 1                  ! upper position of the box 
    222270               IF( ji2 <= jpi .AND. jj2 <= jpj ) THEN                    ! the box is fully included in the local mpi domain 
    223                   p2d(ji:ji2,jj:jj2) = SUM(p2d(ji:ji2,jj:jj2)) 
     271                  p3d(ji:ji2,jj:jj2,jn) = SUM(p3d(ji:ji2,jj:jj2,jn)) 
    224272               ENDIF 
    225273            ENDIF 
    226          END DO 
     274         END_2D 
    227275      END DO 
    228       CALL lbc_lnk( 'lib_fortran', p2d, 'T', 1. ) 
    229       IF( nbondi /= -1 ) THEN 
    230          IF( MOD(mig(    1), 3) == 1 )   p2d(    1,:) = p2d(    2,:) 
    231          IF( MOD(mig(    1), 3) == 2 )   p2d(    2,:) = p2d(    1,:) 
    232       ENDIF 
    233       IF( nbondi /=  1 ) THEN 
    234          IF( MOD(mig(jpi-2), 3) == 1 )   p2d(  jpi,:) = p2d(jpi-1,:) 
    235          IF( MOD(mig(jpi-2), 3) == 0 )   p2d(jpi-1,:) = p2d(  jpi,:) 
    236       ENDIF 
    237       IF( nbondj /= -1 ) THEN 
    238          IF( MOD(mjg(    1), 3) == 1 )   p2d(:,    1) = p2d(:,    2) 
    239          IF( MOD(mjg(    1), 3) == 2 )   p2d(:,    2) = p2d(:,    1) 
    240       ENDIF 
    241       IF( nbondj /=  1 ) THEN 
    242          IF( MOD(mjg(jpj-2), 3) == 1 )   p2d(:,  jpj) = p2d(:,jpj-1) 
    243          IF( MOD(mjg(jpj-2), 3) == 0 )   p2d(:,jpj-1) = p2d(:,  jpj) 
    244       ENDIF 
    245       CALL lbc_lnk( 'lib_fortran', p2d, 'T', 1. ) 
    246  
    247    END SUBROUTINE sum3x3_2d 
    248  
    249    SUBROUTINE sum3x3_3d( p3d ) 
    250       !!----------------------------------------------------------------------- 
    251       !!                  ***  routine sum3x3_3d  *** 
    252       !! 
    253       !! ** Purpose : sum over 3x3 boxes 
    254       !!---------------------------------------------------------------------- 
    255       REAL(wp), DIMENSION (:,:,:), INTENT(inout) ::   p3d 
    256       ! 
    257       INTEGER ::   ji, ji2, jj, jj2, jn     ! dummy loop indices 
    258       INTEGER ::   ipn                      ! Third dimension size 
    259       !!---------------------------------------------------------------------- 
    260       ! 
    261       IF( SIZE(p3d,1) /= jpi ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_3d, the first dimension is not equal to jpi' )  
    262       IF( SIZE(p3d,2) /= jpj ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_3d, the second dimension is not equal to jpj' )  
    263       ipn = SIZE(p3d,3) 
    264       ! 
    265       DO jn = 1, ipn 
    266          DO jj = 1, jpj 
    267             DO ji = 1, jpi  
    268                IF( MOD(mig(ji), 3) == 1 .AND. MOD(mjg(jj), 3) == 1 ) THEN   ! bottom left corber of a 3x3 box 
    269                   ji2 = MIN(mig(ji)+2, jpiglo) - nimpp + 1                  ! right position of the box 
    270                   jj2 = MIN(mjg(jj)+2, jpjglo) - njmpp + 1                  ! upper position of the box 
    271                   IF( ji2 <= jpi .AND. jj2 <= jpj ) THEN                    ! the box is fully included in the local mpi domain 
    272                      p3d(ji:ji2,jj:jj2,jn) = SUM(p3d(ji:ji2,jj:jj2,jn)) 
    273                   ENDIF 
    274                ENDIF 
    275             END DO 
    276          END DO 
    277       END DO 
    278       CALL lbc_lnk( 'lib_fortran', p3d, 'T', 1. ) 
     276      CALL lbc_lnk( 'lib_fortran', p3d, 'T', 1.0_wp ) 
    279277      IF( nbondi /= -1 ) THEN 
    280278         IF( MOD(mig(    1), 3) == 1 )   p3d(    1,:,:) = p3d(    2,:,:) 
     
    293291         IF( MOD(mjg(jpj-2), 3) == 0 )   p3d(:,jpj-1,:) = p3d(:,  jpj,:) 
    294292      ENDIF 
    295       CALL lbc_lnk( 'lib_fortran', p3d, 'T', 1. ) 
     293      CALL lbc_lnk( 'lib_fortran', p3d, 'T', 1.0_wp ) 
    296294 
    297295   END SUBROUTINE sum3x3_3d 
     
    315313      !!              Yun HE and Chris H. Q. DING, Journal of Supercomputing 18, 259-277, 2001 
    316314      !!---------------------------------------------------------------------- 
    317       COMPLEX(wp), INTENT(in   ) ::   ydda 
    318       COMPLEX(wp), INTENT(inout) ::   yddb 
    319       ! 
    320       REAL(wp) :: zerr, zt1, zt2  ! local work variables 
     315      COMPLEX(dp), INTENT(in   ) ::   ydda 
     316      COMPLEX(dp), INTENT(inout) ::   yddb 
     317      ! 
     318      REAL(dp) :: zerr, zt1, zt2  ! local work variables 
    321319      !!----------------------------------------------------------------------- 
    322320      ! 
  • utils/tools/DOMAINcfg/src/lib_fortran_generic.h90

    r14199 r14623  
    4040      REAL(wp)                              ::   FUNCTION_GLOB_OP   ! global sum 
    4141      !! 
    42       COMPLEX(wp)::   ctmp 
     42      COMPLEX(dp)::   ctmp 
    4343      REAL(wp)   ::   ztmp 
    4444      INTEGER    ::   ji, jj, jk   ! dummy loop indices 
     
    5050      ipk = K_SIZE(ptab)   ! 3rd dimension 
    5151      ! 
    52       ctmp = CMPLX( 0.e0, 0.e0, wp )   ! warning ctmp is cumulated 
     52      ctmp = CMPLX( 0.e0, 0.e0, dp )   ! warning ctmp is cumulated 
    5353    
    5454      DO jk = 1, ipk 
     
    5656          DO ji = 1, ipi 
    5757             ztmp =  ARRAY_IN(ji,jj,jk) * MASK_ARRAY(ji,jj) 
    58              CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp ) 
     58             CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp ) 
    5959          END DO 
    6060        END DO 
     
    109109      REAL(wp)                              ::   FUNCTION_GLOB_OP   ! global sum 
    110110      !! 
    111       COMPLEX(wp)::   ctmp 
     111      COMPLEX(dp)::   ctmp 
    112112      REAL(wp)   ::   ztmp 
    113113      INTEGER    ::   jk       ! dummy loop indices 
     
    117117      ipk = K_SIZE(ptab)   ! 3rd dimension 
    118118      ! 
    119       ztmp = ARRAY_OPERATION( ARRAY_IN(:,:,1)) 
     119      ztmp = ARRAY_OPERATION( ARRAY_IN(:,:,1)*tmask_i(:,:) ) 
    120120      DO jk = 2, ipk 
    121          ztmp = SCALAR_OPERATION(ztmp, ARRAY_OPERATION( ARRAY_IN(:,:,jk))) 
     121         ztmp = SCALAR_OPERATION(ztmp, ARRAY_OPERATION( ARRAY_IN(:,:,jk)*tmask_i(:,:) )) 
    122122      ENDDO 
    123123 
  • utils/tools/DOMAINcfg/src/lib_mpp.F90

    r13204 r14623  
    1919   !!            3.2  !  2009  (O. Marti)    add mpp_ini_znl 
    2020   !!            4.0  !  2011  (G. Madec)  move ctl_ routines from in_out_manager 
     21   !!            3.5  !  2012  (S.Mocavero, I. Epicoco) Add mpp_lnk_bdy_3d/2d routines to optimize the BDY comm. 
    2122   !!            3.5  !  2013  (C. Ethe, G. Madec)  message passing arrays as local variables  
    2223   !!            3.5  !  2013  (S.Mocavero, I.Epicoco - CMCC) north fold optimizations 
     
    3132   !!   ctl_opn       : Open file and check if required file is available. 
    3233   !!   ctl_nam       : Prints informations when an error occurs while reading a namelist 
    33    !!   get_unit      : give the index of an unused logical unit 
    34    !!---------------------------------------------------------------------- 
    35 #if   defined key_mpp_mpi 
    36    !!---------------------------------------------------------------------- 
    37    !!   'key_mpp_mpi'             MPI massively parallel processing library 
    38    !!---------------------------------------------------------------------- 
    39    !!   lib_mpp_alloc : allocate mpp arrays 
    40    !!   mynode        : indentify the processor unit 
     34   !!   load_nml      : Read, condense and buffer namelist file into character array for use as an internal file 
     35   !!---------------------------------------------------------------------- 
     36   !!---------------------------------------------------------------------- 
     37   !!   mpp_start     : get local communicator its size and rank 
    4138   !!   mpp_lnk       : interface (defined in lbclnk) for message passing of 2d or 3d arrays (mpp_lnk_2d, mpp_lnk_3d) 
    4239   !!   mpp_lnk_icb   : interface for message passing of 2d arrays with extra halo for icebergs (mpp_lnk_2d_icb) 
     
    5451   !!   mpp_ini_north : initialisation of north fold 
    5552   !!   mpp_lbc_north_icb : alternative to mpp_nfd for extra outer halo with icebergs 
     53   !!   mpp_bcast_nml : broadcast/receive namelist character buffer from reading process to all others 
    5654   !!---------------------------------------------------------------------- 
    5755   USE dom_oce        ! ocean space and time domain 
    58    USE lbcnfd         ! north fold treatment 
    5956   USE in_out_manager ! I/O manager 
    6057 
    6158   IMPLICIT NONE 
    6259   PRIVATE 
    63  
    64    INTERFACE mpp_nfd 
    65       MODULE PROCEDURE   mpp_nfd_2d    , mpp_nfd_3d    , mpp_nfd_4d 
    66       MODULE PROCEDURE   mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr 
    67    END INTERFACE 
    68  
    69    ! Interface associated to the mpp_lnk_... routines is defined in lbclnk 
    70    PUBLIC   mpp_lnk_2d    , mpp_lnk_3d    , mpp_lnk_4d 
    71    PUBLIC   mpp_lnk_2d_ptr, mpp_lnk_3d_ptr, mpp_lnk_4d_ptr 
    7260   ! 
    73 !!gm  this should be useless 
    74    PUBLIC   mpp_nfd_2d    , mpp_nfd_3d    , mpp_nfd_4d 
    75    PUBLIC   mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr 
    76 !!gm end 
    77    ! 
    78    PUBLIC   ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam 
    79    PUBLIC   mynode, mppstop, mppsync, mpp_comm_free 
     61   PUBLIC   ctl_stop, ctl_warn, ctl_opn, ctl_nam, load_nml 
     62   PUBLIC   mpp_start, mppstop, mppsync, mpp_comm_free 
    8063   PUBLIC   mpp_ini_north 
    81    PUBLIC   mpp_lnk_2d_icb 
    82    PUBLIC   mpp_lbc_north_icb 
    8364   PUBLIC   mpp_min, mpp_max, mpp_sum, mpp_minloc, mpp_maxloc 
    8465   PUBLIC   mpp_delay_max, mpp_delay_sum, mpp_delay_rcv 
     
    8667   PUBLIC   mpp_ini_znl 
    8768   PUBLIC   mppsend, mpprecv                          ! needed by TAM and ICB routines 
     69   PUBLIC   mppsend_sp, mpprecv_sp                          ! needed by TAM and ICB routines 
     70   PUBLIC   mppsend_dp, mpprecv_dp                          ! needed by TAM and ICB routines 
     71   PUBLIC   mpp_report 
     72   PUBLIC   mpp_bcast_nml 
     73   PUBLIC   tic_tac 
     74#if ! defined key_mpp_mpi 
     75   PUBLIC MPI_Wtime 
     76#endif 
    8877    
    8978   !! * Interfaces 
     
    9281   !! for the compilation on AIX system as well as NEC and SGI. Ok on COMPACQ 
    9382   INTERFACE mpp_min 
    94       MODULE PROCEDURE mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real 
     83      MODULE PROCEDURE mppmin_a_int, mppmin_int 
     84      MODULE PROCEDURE mppmin_a_real_sp, mppmin_real_sp 
     85      MODULE PROCEDURE mppmin_a_real_dp, mppmin_real_dp 
    9586   END INTERFACE 
    9687   INTERFACE mpp_max 
    97       MODULE PROCEDURE mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real 
     88      MODULE PROCEDURE mppmax_a_int, mppmax_int 
     89      MODULE PROCEDURE mppmax_a_real_sp, mppmax_real_sp 
     90      MODULE PROCEDURE mppmax_a_real_dp, mppmax_real_dp 
    9891   END INTERFACE 
    9992   INTERFACE mpp_sum 
    100       MODULE PROCEDURE mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real,   & 
    101          &             mppsum_realdd, mppsum_a_realdd 
     93      MODULE PROCEDURE mppsum_a_int, mppsum_int 
     94      MODULE PROCEDURE mppsum_realdd, mppsum_a_realdd 
     95      MODULE PROCEDURE mppsum_a_real_sp, mppsum_real_sp 
     96      MODULE PROCEDURE mppsum_a_real_dp, mppsum_real_dp 
    10297   END INTERFACE 
    10398   INTERFACE mpp_minloc 
    104       MODULE PROCEDURE mpp_minloc2d ,mpp_minloc3d 
     99      MODULE PROCEDURE mpp_minloc2d_sp ,mpp_minloc3d_sp 
     100      MODULE PROCEDURE mpp_minloc2d_dp ,mpp_minloc3d_dp 
    105101   END INTERFACE 
    106102   INTERFACE mpp_maxloc 
    107       MODULE PROCEDURE mpp_maxloc2d ,mpp_maxloc3d 
     103      MODULE PROCEDURE mpp_maxloc2d_sp ,mpp_maxloc3d_sp 
     104      MODULE PROCEDURE mpp_maxloc2d_dp ,mpp_maxloc3d_dp 
    108105   END INTERFACE 
    109106 
     
    111108   !!  MPI  variable definition !! 
    112109   !! ========================= !! 
     110#if   defined key_mpp_mpi 
    113111!$AGRIF_DO_NOT_TREAT 
    114112   INCLUDE 'mpif.h' 
    115113!$AGRIF_END_DO_NOT_TREAT 
    116  
    117114   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .TRUE.    !: mpp flag 
     115#else    
     116   INTEGER, PUBLIC, PARAMETER ::   MPI_STATUS_SIZE = 1 
     117   INTEGER, PUBLIC, PARAMETER ::   MPI_DOUBLE_PRECISION = 8 
     118   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .FALSE.    !: mpp flag 
     119#endif 
    118120 
    119121   INTEGER, PARAMETER         ::   nprocmax = 2**10   ! maximun dimension (required to be a power of 2) 
     
    144146   INTEGER, PUBLIC, DIMENSION(:), ALLOCATABLE, SAVE ::   nrank_north   !: dimension ndim_rank_north 
    145147 
    146    ! Type of send : standard, buffered, immediate 
    147    CHARACTER(len=1), PUBLIC ::   cn_mpi_send        !: type od mpi send/recieve (S=standard, B=bsend, I=isend) 
    148    LOGICAL         , PUBLIC ::   l_isend = .FALSE.  !: isend use indicator (T if cn_mpi_send='I') 
    149    INTEGER         , PUBLIC ::   nn_buffer          !: size of the buffer in case of mpi_bsend 
    150  
    151148   ! Communications summary report 
    152    CHARACTER(len=400), DIMENSION(:), ALLOCATABLE ::   crname_lbc                   !: names of lbc_lnk calling routines 
    153    CHARACTER(len=400), DIMENSION(:), ALLOCATABLE ::   crname_glb                   !: names of global comm calling routines 
    154    CHARACTER(len=400), DIMENSION(:), ALLOCATABLE ::   crname_dlg                   !: names of delayed global comm calling routines 
     149   CHARACTER(len=lca), DIMENSION(:), ALLOCATABLE ::   crname_lbc                   !: names of lbc_lnk calling routines 
     150   CHARACTER(len=lca), DIMENSION(:), ALLOCATABLE ::   crname_glb                   !: names of global comm calling routines 
     151   CHARACTER(len=lca), DIMENSION(:), ALLOCATABLE ::   crname_dlg                   !: names of delayed global comm calling routines 
    155152   INTEGER, PUBLIC                               ::   ncom_stp = 0                 !: copy of time step # istp 
    156153   INTEGER, PUBLIC                               ::   ncom_fsbc = 1                !: copy of sbc time step # nn_fsbc 
    157    INTEGER, PUBLIC                               ::   ncom_dttrc = 1               !: copy of top time step # nn_dttrc 
    158154   INTEGER, PUBLIC                               ::   ncom_freq                    !: frequency of comm diagnostic 
    159155   INTEGER, PUBLIC , DIMENSION(:,:), ALLOCATABLE ::   ncomm_sequence               !: size of communicated arrays (halos) 
    160    INTEGER, PARAMETER, PUBLIC                    ::   ncom_rec_max = 3000          !: max number of communication record 
     156   INTEGER, PARAMETER, PUBLIC                    ::   ncom_rec_max = 5000          !: max number of communication record 
    161157   INTEGER, PUBLIC                               ::   n_sequence_lbc = 0           !: # of communicated arraysvia lbc 
    162158   INTEGER, PUBLIC                               ::   n_sequence_glb = 0           !: # of global communications 
     
    172168   TYPE, PUBLIC ::   DELAYARR 
    173169      REAL(   wp), POINTER, DIMENSION(:) ::  z1d => NULL() 
    174       COMPLEX(wp), POINTER, DIMENSION(:) ::  y1d => NULL() 
     170      COMPLEX(dp), POINTER, DIMENSION(:) ::  y1d => NULL() 
    175171   END TYPE DELAYARR 
    176    TYPE( DELAYARR ), DIMENSION(nbdelay), PUBLIC  ::   todelay               
    177    INTEGER,          DIMENSION(nbdelay), PUBLIC  ::   ndelayid = -1     !: mpi request id of the delayed operations 
    178  
     172   TYPE( DELAYARR ), DIMENSION(nbdelay), PUBLIC, SAVE  ::   todelay         !: must have SAVE for default initialization of DELAYARR 
     173   INTEGER,          DIMENSION(nbdelay), PUBLIC        ::   ndelayid = -1   !: mpi request id of the delayed operations 
     174 
     175   ! timing summary report 
     176   REAL(dp), DIMENSION(2), PUBLIC ::  waiting_time = 0._dp 
     177   REAL(dp)              , PUBLIC ::  compute_time = 0._dp, elapsed_time = 0._dp 
     178    
    179179   REAL(wp), DIMENSION(:), ALLOCATABLE, SAVE ::   tampon   ! buffer in case of bsend 
    180180 
    181181   LOGICAL, PUBLIC ::   ln_nnogather                !: namelist control of northfold comms 
    182182   LOGICAL, PUBLIC ::   l_north_nogather = .FALSE.  !: internal control of northfold comms 
    183  
     183    
     184   !! * Substitutions 
     185#  include "do_loop_substitute.h90" 
    184186   !!---------------------------------------------------------------------- 
    185187   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    186    !! $Id: lib_mpp.F90 10538 2019-01-17 10:41:10Z clem $ 
     188   !! $Id: lib_mpp.F90 13286 2020-07-09 15:48:29Z smasson $ 
    187189   !! Software governed by the CeCILL license (see ./LICENSE) 
    188190   !!---------------------------------------------------------------------- 
    189191CONTAINS 
    190192 
    191    FUNCTION mynode( ldtxt, ldname, kumnam_ref, kumnam_cfg, kumond, kstop, localComm ) 
    192       !!---------------------------------------------------------------------- 
    193       !!                  ***  routine mynode  *** 
    194       !! 
    195       !! ** Purpose :   Find processor unit 
    196       !!---------------------------------------------------------------------- 
    197       CHARACTER(len=*),DIMENSION(:), INTENT(  out) ::   ldtxt        ! 
    198       CHARACTER(len=*)             , INTENT(in   ) ::   ldname       ! 
    199       INTEGER                      , INTENT(in   ) ::   kumnam_ref   ! logical unit for reference namelist 
    200       INTEGER                      , INTENT(in   ) ::   kumnam_cfg   ! logical unit for configuration namelist 
    201       INTEGER                      , INTENT(inout) ::   kumond       ! logical unit for namelist output 
    202       INTEGER                      , INTENT(inout) ::   kstop        ! stop indicator 
     193   SUBROUTINE mpp_start( localComm ) 
     194      !!---------------------------------------------------------------------- 
     195      !!                  ***  routine mpp_start  *** 
     196      !! 
     197      !! ** Purpose :   get mpi_comm_oce, mpprank and mppsize 
     198      !!---------------------------------------------------------------------- 
    203199      INTEGER         , OPTIONAL   , INTENT(in   ) ::   localComm    ! 
    204200      ! 
    205       INTEGER ::   mynode, ierr, code, ji, ii, ios 
    206       LOGICAL ::   mpi_was_called 
    207       ! 
    208       NAMELIST/nammpp/ cn_mpi_send, nn_buffer, jpni, jpnj, ln_nnogather 
    209       !!---------------------------------------------------------------------- 
    210       ! 
    211       ii = 1 
    212       WRITE(ldtxt(ii),*)                                                                  ;   ii = ii + 1 
    213       WRITE(ldtxt(ii),*) 'mynode : mpi initialisation'                                    ;   ii = ii + 1 
    214       WRITE(ldtxt(ii),*) '~~~~~~ '                                                        ;   ii = ii + 1 
    215       ! 
    216       REWIND( kumnam_ref )              ! Namelist nammpp in reference namelist: mpi variables 
    217       READ  ( kumnam_ref, nammpp, IOSTAT = ios, ERR = 901) 
    218 901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'nammpp in reference namelist', lwp ) 
    219       ! 
    220       REWIND( kumnam_cfg )              ! Namelist nammpp in configuration namelist: mpi variables 
    221       READ  ( kumnam_cfg, nammpp, IOSTAT = ios, ERR = 902 ) 
    222 902   IF( ios >  0 )   CALL ctl_nam ( ios , 'nammpp in configuration namelist', lwp ) 
    223       ! 
    224       !                              ! control print 
    225       WRITE(ldtxt(ii),*) '   Namelist nammpp'                                             ;   ii = ii + 1 
    226       WRITE(ldtxt(ii),*) '      mpi send type          cn_mpi_send = ', cn_mpi_send       ;   ii = ii + 1 
    227       WRITE(ldtxt(ii),*) '      size exported buffer   nn_buffer   = ', nn_buffer,' bytes';   ii = ii + 1 
    228       ! 
    229       IF( jpni < 1 .OR. jpnj < 1  ) THEN 
    230          WRITE(ldtxt(ii),*) '      jpni and jpnj will be calculated automatically' ;   ii = ii + 1 
    231       ELSE 
    232          WRITE(ldtxt(ii),*) '      processor grid extent in i         jpni = ',jpni       ;   ii = ii + 1 
    233          WRITE(ldtxt(ii),*) '      processor grid extent in j         jpnj = ',jpnj       ;   ii = ii + 1 
    234       ENDIF 
    235  
    236       WRITE(ldtxt(ii),*) '      avoid use of mpi_allgather at the north fold  ln_nnogather = ', ln_nnogather  ; ii = ii + 1 
    237  
    238       CALL mpi_initialized ( mpi_was_called, code ) 
    239       IF( code /= MPI_SUCCESS ) THEN 
    240          DO ji = 1, SIZE(ldtxt) 
    241             IF( TRIM(ldtxt(ji)) /= '' )   WRITE(*,*) ldtxt(ji)      ! control print of mynode 
    242          END DO 
    243          WRITE(*, cform_err) 
    244          WRITE(*, *) 'lib_mpp: Error in routine mpi_initialized' 
    245          CALL mpi_abort( mpi_comm_world, code, ierr ) 
    246       ENDIF 
    247  
    248       IF( mpi_was_called ) THEN 
    249          ! 
    250          SELECT CASE ( cn_mpi_send ) 
    251          CASE ( 'S' )                ! Standard mpi send (blocking) 
    252             WRITE(ldtxt(ii),*) '           Standard blocking mpi send (send)'             ;   ii = ii + 1 
    253          CASE ( 'B' )                ! Buffer mpi send (blocking) 
    254             WRITE(ldtxt(ii),*) '           Buffer blocking mpi send (bsend)'              ;   ii = ii + 1 
    255             IF( Agrif_Root() )   CALL mpi_init_oce( ldtxt, ii, ierr ) 
    256          CASE ( 'I' )                ! Immediate mpi send (non-blocking send) 
    257             WRITE(ldtxt(ii),*) '           Immediate non-blocking send (isend)'           ;   ii = ii + 1 
    258             l_isend = .TRUE. 
    259          CASE DEFAULT 
    260             WRITE(ldtxt(ii),cform_err)                                                    ;   ii = ii + 1 
    261             WRITE(ldtxt(ii),*) '           bad value for cn_mpi_send = ', cn_mpi_send     ;   ii = ii + 1 
    262             kstop = kstop + 1 
    263          END SELECT 
    264          ! 
    265       ELSEIF ( PRESENT(localComm) .AND. .NOT. mpi_was_called ) THEN 
    266          WRITE(ldtxt(ii),cform_err)                                                    ;   ii = ii + 1 
    267          WRITE(ldtxt(ii),*) ' lib_mpp: You cannot provide a local communicator '          ;   ii = ii + 1 
    268          WRITE(ldtxt(ii),*) '          without calling MPI_Init before ! '                ;   ii = ii + 1 
    269          kstop = kstop + 1 
    270       ELSE 
    271          SELECT CASE ( cn_mpi_send ) 
    272          CASE ( 'S' )                ! Standard mpi send (blocking) 
    273             WRITE(ldtxt(ii),*) '           Standard blocking mpi send (send)'             ;   ii = ii + 1 
    274             CALL mpi_init( ierr ) 
    275          CASE ( 'B' )                ! Buffer mpi send (blocking) 
    276             WRITE(ldtxt(ii),*) '           Buffer blocking mpi send (bsend)'              ;   ii = ii + 1 
    277             IF( Agrif_Root() )   CALL mpi_init_oce( ldtxt, ii, ierr ) 
    278          CASE ( 'I' )                ! Immediate mpi send (non-blocking send) 
    279             WRITE(ldtxt(ii),*) '           Immediate non-blocking send (isend)'           ;   ii = ii + 1 
    280             l_isend = .TRUE. 
    281             CALL mpi_init( ierr ) 
    282          CASE DEFAULT 
    283             WRITE(ldtxt(ii),cform_err)                                                    ;   ii = ii + 1 
    284             WRITE(ldtxt(ii),*) '           bad value for cn_mpi_send = ', cn_mpi_send     ;   ii = ii + 1 
    285             kstop = kstop + 1 
    286          END SELECT 
    287          ! 
    288       ENDIF 
    289  
     201      INTEGER ::   ierr 
     202      LOGICAL ::   llmpi_init 
     203      !!---------------------------------------------------------------------- 
     204#if defined key_mpp_mpi 
     205      ! 
     206      CALL mpi_initialized ( llmpi_init, ierr ) 
     207      IF( ierr /= MPI_SUCCESS ) CALL ctl_stop( 'STOP', ' lib_mpp: Error in routine mpi_initialized' ) 
     208 
     209      IF( .NOT. llmpi_init ) THEN 
     210         IF( PRESENT(localComm) ) THEN 
     211            WRITE(ctmp1,*) ' lib_mpp: You cannot provide a local communicator ' 
     212            WRITE(ctmp2,*) '          without calling MPI_Init before ! ' 
     213            CALL ctl_stop( 'STOP', ctmp1, ctmp2 ) 
     214         ENDIF 
     215         CALL mpi_init( ierr ) 
     216         IF( ierr /= MPI_SUCCESS ) CALL ctl_stop( 'STOP', ' lib_mpp: Error in routine mpi_init' ) 
     217      ENDIF 
     218        
    290219      IF( PRESENT(localComm) ) THEN 
    291220         IF( Agrif_Root() ) THEN 
     
    293222         ENDIF 
    294223      ELSE 
    295          CALL mpi_comm_dup( mpi_comm_world, mpi_comm_oce, code) 
    296          IF( code /= MPI_SUCCESS ) THEN 
    297             DO ji = 1, SIZE(ldtxt) 
    298                IF( TRIM(ldtxt(ji)) /= '' )   WRITE(*,*) ldtxt(ji)      ! control print of mynode 
    299             END DO 
    300             WRITE(*, cform_err) 
    301             WRITE(*, *) ' lib_mpp: Error in routine mpi_comm_dup' 
    302             CALL mpi_abort( mpi_comm_world, code, ierr ) 
    303          ENDIF 
    304       ENDIF 
    305  
    306 #if defined key_agrif 
     224         CALL mpi_comm_dup( mpi_comm_world, mpi_comm_oce, ierr) 
     225         IF( ierr /= MPI_SUCCESS ) CALL ctl_stop( 'STOP', ' lib_mpp: Error in routine mpi_comm_dup' ) 
     226      ENDIF 
     227 
     228# if defined key_agrif 
    307229      IF( Agrif_Root() ) THEN 
    308230         CALL Agrif_MPI_Init(mpi_comm_oce) 
     
    310232         CALL Agrif_MPI_set_grid_comm(mpi_comm_oce) 
    311233      ENDIF 
    312 #endif 
     234# endif 
    313235 
    314236      CALL mpi_comm_rank( mpi_comm_oce, mpprank, ierr ) 
    315237      CALL mpi_comm_size( mpi_comm_oce, mppsize, ierr ) 
    316       mynode = mpprank 
    317  
    318       IF( mynode == 0 ) THEN 
    319          CALL ctl_opn( kumond, TRIM(ldname), 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. , 1 ) 
    320          WRITE(kumond, nammpp)       
    321       ENDIF 
    322238      ! 
    323239      CALL MPI_OP_CREATE(DDPDD_MPI, .TRUE., MPI_SUMDD, ierr) 
    324240      ! 
    325    END FUNCTION mynode 
    326  
    327    !!---------------------------------------------------------------------- 
    328    !!                   ***  routine mpp_lnk_(2,3,4)d  *** 
    329    !! 
    330    !!   * Argument : dummy argument use in mpp_lnk_... routines 
    331    !!                ptab   :   array or pointer of arrays on which the boundary condition is applied 
    332    !!                cd_nat :   nature of array grid-points 
    333    !!                psgn   :   sign used across the north fold boundary 
    334    !!                kfld   :   optional, number of pt3d arrays 
    335    !!                cd_mpp :   optional, fill the overlap area only 
    336    !!                pval   :   optional, background value (used at closed boundaries) 
    337    !!---------------------------------------------------------------------- 
    338    ! 
    339    !                       !==  2D array and array of 2D pointer  ==! 
    340    ! 
    341 #  define DIM_2d 
    342 #     define ROUTINE_LNK           mpp_lnk_2d 
    343 #     include "mpp_lnk_generic.h90" 
    344 #     undef ROUTINE_LNK 
    345 #     define MULTI 
    346 #     define ROUTINE_LNK           mpp_lnk_2d_ptr 
    347 #     include "mpp_lnk_generic.h90" 
    348 #     undef ROUTINE_LNK 
    349 #     undef MULTI 
    350 #  undef DIM_2d 
    351    ! 
    352    !                       !==  3D array and array of 3D pointer  ==! 
    353    ! 
    354 #  define DIM_3d 
    355 #     define ROUTINE_LNK           mpp_lnk_3d 
    356 #     include "mpp_lnk_generic.h90" 
    357 #     undef ROUTINE_LNK 
    358 #     define MULTI 
    359 #     define ROUTINE_LNK           mpp_lnk_3d_ptr 
    360 #     include "mpp_lnk_generic.h90" 
    361 #     undef ROUTINE_LNK 
    362 #     undef MULTI 
    363 #  undef DIM_3d 
    364    ! 
    365    !                       !==  4D array and array of 4D pointer  ==! 
    366    ! 
    367 #  define DIM_4d 
    368 #     define ROUTINE_LNK           mpp_lnk_4d 
    369 #     include "mpp_lnk_generic.h90" 
    370 #     undef ROUTINE_LNK 
    371 #     define MULTI 
    372 #     define ROUTINE_LNK           mpp_lnk_4d_ptr 
    373 #     include "mpp_lnk_generic.h90" 
    374 #     undef ROUTINE_LNK 
    375 #     undef MULTI 
    376 #  undef DIM_4d 
    377  
    378    !!---------------------------------------------------------------------- 
    379    !!                   ***  routine mpp_nfd_(2,3,4)d  *** 
    380    !! 
    381    !!   * Argument : dummy argument use in mpp_nfd_... routines 
    382    !!                ptab   :   array or pointer of arrays on which the boundary condition is applied 
    383    !!                cd_nat :   nature of array grid-points 
    384    !!                psgn   :   sign used across the north fold boundary 
    385    !!                kfld   :   optional, number of pt3d arrays 
    386    !!                cd_mpp :   optional, fill the overlap area only 
    387    !!                pval   :   optional, background value (used at closed boundaries) 
    388    !!---------------------------------------------------------------------- 
    389    ! 
    390    !                       !==  2D array and array of 2D pointer  ==! 
    391    ! 
    392 #  define DIM_2d 
    393 #     define ROUTINE_NFD           mpp_nfd_2d 
    394 #     include "mpp_nfd_generic.h90" 
    395 #     undef ROUTINE_NFD 
    396 #     define MULTI 
    397 #     define ROUTINE_NFD           mpp_nfd_2d_ptr 
    398 #     include "mpp_nfd_generic.h90" 
    399 #     undef ROUTINE_NFD 
    400 #     undef MULTI 
    401 #  undef DIM_2d 
    402    ! 
    403    !                       !==  3D array and array of 3D pointer  ==! 
    404    ! 
    405 #  define DIM_3d 
    406 #     define ROUTINE_NFD           mpp_nfd_3d 
    407 #     include "mpp_nfd_generic.h90" 
    408 #     undef ROUTINE_NFD 
    409 #     define MULTI 
    410 #     define ROUTINE_NFD           mpp_nfd_3d_ptr 
    411 #     include "mpp_nfd_generic.h90" 
    412 #     undef ROUTINE_NFD 
    413 #     undef MULTI 
    414 #  undef DIM_3d 
    415    ! 
    416    !                       !==  4D array and array of 4D pointer  ==! 
    417    ! 
    418 #  define DIM_4d 
    419 #     define ROUTINE_NFD           mpp_nfd_4d 
    420 #     include "mpp_nfd_generic.h90" 
    421 #     undef ROUTINE_NFD 
    422 #     define MULTI 
    423 #     define ROUTINE_NFD           mpp_nfd_4d_ptr 
    424 #     include "mpp_nfd_generic.h90" 
    425 #     undef ROUTINE_NFD 
    426 #     undef MULTI 
    427 #  undef DIM_4d 
    428  
    429  
    430    !!---------------------------------------------------------------------- 
    431    !! 
    432    !!   load_array  &   mpp_lnk_2d_9    à generaliser a 3D et 4D 
    433     
    434     
    435    !!    mpp_lnk_sum_2d et 3D   ====>>>>>>   à virer du code !!!! 
    436     
    437     
    438    !!---------------------------------------------------------------------- 
    439  
     241#else 
     242      IF( PRESENT( localComm ) ) mpi_comm_oce = localComm 
     243      mppsize = 1 
     244      mpprank = 0 
     245#endif 
     246   END SUBROUTINE mpp_start 
    440247 
    441248 
     
    454261      !! 
    455262      INTEGER ::   iflag 
    456       !!---------------------------------------------------------------------- 
    457       ! 
    458       SELECT CASE ( cn_mpi_send ) 
    459       CASE ( 'S' )                ! Standard mpi send (blocking) 
    460          CALL mpi_send ( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce        , iflag ) 
    461       CASE ( 'B' )                ! Buffer mpi send (blocking) 
    462          CALL mpi_bsend( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce        , iflag ) 
    463       CASE ( 'I' )                ! Immediate mpi send (non-blocking send) 
    464          ! be carefull, one more argument here : the mpi request identifier.. 
    465          CALL mpi_isend( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 
    466       END SELECT 
     263      INTEGER :: mpi_working_type 
     264      !!---------------------------------------------------------------------- 
     265      ! 
     266#if defined key_mpp_mpi 
     267      IF (wp == dp) THEN 
     268         mpi_working_type = mpi_double_precision 
     269      ELSE 
     270         mpi_working_type = mpi_real 
     271      END IF 
     272      CALL mpi_isend( pmess, kbytes, mpi_working_type, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 
     273#endif 
    467274      ! 
    468275   END SUBROUTINE mppsend 
     276 
     277 
     278   SUBROUTINE mppsend_dp( ktyp, pmess, kbytes, kdest, md_req ) 
     279      !!---------------------------------------------------------------------- 
     280      !!                  ***  routine mppsend  *** 
     281      !! 
     282      !! ** Purpose :   Send messag passing array 
     283      !! 
     284      !!---------------------------------------------------------------------- 
     285      REAL(dp), INTENT(inout) ::   pmess(*)   ! array of real 
     286      INTEGER , INTENT(in   ) ::   kbytes     ! size of the array pmess 
     287      INTEGER , INTENT(in   ) ::   kdest      ! receive process number 
     288      INTEGER , INTENT(in   ) ::   ktyp       ! tag of the message 
     289      INTEGER , INTENT(in   ) ::   md_req     ! argument for isend 
     290      !! 
     291      INTEGER ::   iflag 
     292      !!---------------------------------------------------------------------- 
     293      ! 
     294#if defined key_mpp_mpi 
     295      CALL mpi_isend( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 
     296#endif 
     297      ! 
     298   END SUBROUTINE mppsend_dp 
     299 
     300 
     301   SUBROUTINE mppsend_sp( ktyp, pmess, kbytes, kdest, md_req ) 
     302      !!---------------------------------------------------------------------- 
     303      !!                  ***  routine mppsend  *** 
     304      !! 
     305      !! ** Purpose :   Send messag passing array 
     306      !! 
     307      !!---------------------------------------------------------------------- 
     308      REAL(sp), INTENT(inout) ::   pmess(*)   ! array of real 
     309      INTEGER , INTENT(in   ) ::   kbytes     ! size of the array pmess 
     310      INTEGER , INTENT(in   ) ::   kdest      ! receive process number 
     311      INTEGER , INTENT(in   ) ::   ktyp       ! tag of the message 
     312      INTEGER , INTENT(in   ) ::   md_req     ! argument for isend 
     313      !! 
     314      INTEGER ::   iflag 
     315      !!---------------------------------------------------------------------- 
     316      ! 
     317#if defined key_mpp_mpi 
     318      CALL mpi_isend( pmess, kbytes, mpi_real, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 
     319#endif 
     320      ! 
     321   END SUBROUTINE mppsend_sp 
    469322 
    470323 
     
    484337      INTEGER :: iflag 
    485338      INTEGER :: use_source 
    486       !!---------------------------------------------------------------------- 
    487       ! 
     339      INTEGER :: mpi_working_type 
     340      !!---------------------------------------------------------------------- 
     341      ! 
     342#if defined key_mpp_mpi 
    488343      ! If a specific process number has been passed to the receive call, 
    489344      ! use that one. Default is to use mpi_any_source 
     
    491346      IF( PRESENT(ksource) )   use_source = ksource 
    492347      ! 
     348      IF (wp == dp) THEN 
     349         mpi_working_type = mpi_double_precision 
     350      ELSE 
     351         mpi_working_type = mpi_real 
     352      END IF 
     353      CALL mpi_recv( pmess, kbytes, mpi_working_type, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 
     354#endif 
     355      ! 
     356   END SUBROUTINE mpprecv 
     357 
     358   SUBROUTINE mpprecv_dp( ktyp, pmess, kbytes, ksource ) 
     359      !!---------------------------------------------------------------------- 
     360      !!                  ***  routine mpprecv  *** 
     361      !! 
     362      !! ** Purpose :   Receive messag passing array 
     363      !! 
     364      !!---------------------------------------------------------------------- 
     365      REAL(dp), INTENT(inout) ::   pmess(*)   ! array of real 
     366      INTEGER , INTENT(in   ) ::   kbytes     ! suze of the array pmess 
     367      INTEGER , INTENT(in   ) ::   ktyp       ! Tag of the recevied message 
     368      INTEGER, OPTIONAL, INTENT(in) :: ksource    ! source process number 
     369      !! 
     370      INTEGER :: istatus(mpi_status_size) 
     371      INTEGER :: iflag 
     372      INTEGER :: use_source 
     373      !!---------------------------------------------------------------------- 
     374      ! 
     375#if defined key_mpp_mpi 
     376      ! If a specific process number has been passed to the receive call, 
     377      ! use that one. Default is to use mpi_any_source 
     378      use_source = mpi_any_source 
     379      IF( PRESENT(ksource) )   use_source = ksource 
     380      ! 
    493381      CALL mpi_recv( pmess, kbytes, mpi_double_precision, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 
    494       ! 
    495    END SUBROUTINE mpprecv 
     382#endif 
     383      ! 
     384   END SUBROUTINE mpprecv_dp 
     385 
     386 
     387   SUBROUTINE mpprecv_sp( ktyp, pmess, kbytes, ksource ) 
     388      !!---------------------------------------------------------------------- 
     389      !!                  ***  routine mpprecv  *** 
     390      !! 
     391      !! ** Purpose :   Receive messag passing array 
     392      !! 
     393      !!---------------------------------------------------------------------- 
     394      REAL(sp), INTENT(inout) ::   pmess(*)   ! array of real 
     395      INTEGER , INTENT(in   ) ::   kbytes     ! suze of the array pmess 
     396      INTEGER , INTENT(in   ) ::   ktyp       ! Tag of the recevied message 
     397      INTEGER, OPTIONAL, INTENT(in) :: ksource    ! source process number 
     398      !! 
     399      INTEGER :: istatus(mpi_status_size) 
     400      INTEGER :: iflag 
     401      INTEGER :: use_source 
     402      !!---------------------------------------------------------------------- 
     403      ! 
     404#if defined key_mpp_mpi 
     405      ! If a specific process number has been passed to the receive call, 
     406      ! use that one. Default is to use mpi_any_source 
     407      use_source = mpi_any_source 
     408      IF( PRESENT(ksource) )   use_source = ksource 
     409      ! 
     410      CALL mpi_recv( pmess, kbytes, mpi_real, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 
     411#endif 
     412      ! 
     413   END SUBROUTINE mpprecv_sp 
    496414 
    497415 
     
    512430      ! 
    513431      itaille = jpi * jpj 
     432#if defined key_mpp_mpi 
    514433      CALL mpi_gather( ptab, itaille, mpi_double_precision, pio, itaille     ,   & 
    515434         &                            mpi_double_precision, kp , mpi_comm_oce, ierror ) 
     435#else 
     436      pio(:,:,1) = ptab(:,:) 
     437#endif 
    516438      ! 
    517439   END SUBROUTINE mppgather 
     
    535457      itaille = jpi * jpj 
    536458      ! 
     459#if defined key_mpp_mpi 
    537460      CALL mpi_scatter( pio, itaille, mpi_double_precision, ptab, itaille     ,   & 
    538461         &                            mpi_double_precision, kp  , mpi_comm_oce, ierror ) 
     462#else 
     463      ptab(:,:) = pio(:,:,1) 
     464#endif 
    539465      ! 
    540466   END SUBROUTINE mppscatter 
     
    550476      CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine 
    551477      CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation 
    552       COMPLEX(wp),      INTENT(in   ), DIMENSION(:) ::   y_in 
     478      COMPLEX(dp),      INTENT(in   ), DIMENSION(:) ::   y_in 
    553479      REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout 
    554480      LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine 
     
    558484      INTEGER ::   idvar 
    559485      INTEGER ::   ierr, ilocalcomm 
    560       COMPLEX(wp), ALLOCATABLE, DIMENSION(:) ::   ytmp 
    561       !!---------------------------------------------------------------------- 
     486      COMPLEX(dp), ALLOCATABLE, DIMENSION(:) ::   ytmp 
     487      !!---------------------------------------------------------------------- 
     488#if defined key_mpp_mpi 
    562489      ilocalcomm = mpi_comm_oce 
    563490      IF( PRESENT(kcom) )   ilocalcomm = kcom 
     
    598525 
    599526      ! send y_in into todelay(idvar)%y1d with a non-blocking communication 
    600 #if defined key_mpi2 
    601       CALL  mpi_allreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr ) 
     527# if defined key_mpi2 
     528      IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
     529      CALL  mpi_allreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ierr ) 
     530      ndelayid(idvar) = 1 
     531      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
     532# else 
     533      CALL mpi_iallreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr ) 
     534# endif 
    602535#else 
    603       CALL mpi_iallreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr ) 
     536      pout(:) = REAL(y_in(:), wp) 
    604537#endif 
    605538 
     
    624557      INTEGER ::   idvar 
    625558      INTEGER ::   ierr, ilocalcomm 
    626       !!---------------------------------------------------------------------- 
     559      INTEGER ::   MPI_TYPE 
     560      !!---------------------------------------------------------------------- 
     561       
     562#if defined key_mpp_mpi 
     563      if( wp == dp ) then 
     564         MPI_TYPE = MPI_DOUBLE_PRECISION 
     565      else if ( wp == sp ) then 
     566         MPI_TYPE = MPI_REAL 
     567      else 
     568        CALL ctl_stop( "Error defining type, wp is neither dp nor sp" ) 
     569    
     570      end if 
     571 
    627572      ilocalcomm = mpi_comm_oce 
    628573      IF( PRESENT(kcom) )   ilocalcomm = kcom 
     
    659604 
    660605      ! send p_in into todelay(idvar)%z1d with a non-blocking communication 
    661 #if defined key_mpi2 
    662       CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 
     606# if defined key_mpi2 
     607      IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
     608      CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_TYPE, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 
     609      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
     610# else 
     611      CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_TYPE, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 
     612# endif 
    663613#else 
    664       CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 
     614      pout(:) = p_in(:) 
    665615#endif 
    666616 
     
    678628      INTEGER ::   ierr 
    679629      !!---------------------------------------------------------------------- 
     630#if defined key_mpp_mpi 
    680631      IF( ndelayid(kid) /= -2 ) THEN   
    681632#if ! defined key_mpi2 
     633         IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 
    682634         CALL mpi_wait( ndelayid(kid), MPI_STATUS_IGNORE, ierr )                        ! make sure todelay(kid) is received 
     635         IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
    683636#endif 
    684637         IF( ASSOCIATED(todelay(kid)%y1d) )   todelay(kid)%z1d(:) = REAL(todelay(kid)%y1d(:), wp)  ! define %z1d from %y1d 
    685638         ndelayid(kid) = -2   ! add flag to know that mpi_wait was already called on kid 
    686639      ENDIF 
     640#endif 
    687641   END SUBROUTINE mpp_delay_rcv 
     642 
     643   SUBROUTINE mpp_bcast_nml( cdnambuff , kleng ) 
     644      CHARACTER(LEN=:)    , ALLOCATABLE, INTENT(INOUT) :: cdnambuff 
     645      INTEGER                          , INTENT(INOUT) :: kleng 
     646      !!---------------------------------------------------------------------- 
     647      !!                  ***  routine mpp_bcast_nml  *** 
     648      !! 
     649      !! ** Purpose :   broadcast namelist character buffer 
     650      !! 
     651      !!---------------------------------------------------------------------- 
     652      !! 
     653      INTEGER ::   iflag 
     654      !!---------------------------------------------------------------------- 
     655      ! 
     656#if defined key_mpp_mpi 
     657      call MPI_BCAST(kleng, 1, MPI_INT, 0, mpi_comm_oce, iflag) 
     658      call MPI_BARRIER(mpi_comm_oce, iflag) 
     659!$AGRIF_DO_NOT_TREAT 
     660      IF ( .NOT. ALLOCATED(cdnambuff) ) ALLOCATE( CHARACTER(LEN=kleng) :: cdnambuff ) 
     661!$AGRIF_END_DO_NOT_TREAT 
     662      call MPI_BCAST(cdnambuff, kleng, MPI_CHARACTER, 0, mpi_comm_oce, iflag) 
     663      call MPI_BARRIER(mpi_comm_oce, iflag) 
     664#endif 
     665      ! 
     666   END SUBROUTINE mpp_bcast_nml 
    688667 
    689668    
     
    707686#  undef INTEGER_TYPE 
    708687! 
     688   !! 
     689   !!   ----   SINGLE PRECISION VERSIONS 
     690   !! 
     691#  define SINGLE_PRECISION 
    709692#  define REAL_TYPE 
    710693#  define DIM_0d 
    711 #     define ROUTINE_ALLREDUCE           mppmax_real 
     694#     define ROUTINE_ALLREDUCE           mppmax_real_sp 
    712695#     include "mpp_allreduce_generic.h90" 
    713696#     undef ROUTINE_ALLREDUCE 
    714697#  undef DIM_0d 
    715698#  define DIM_1d 
    716 #     define ROUTINE_ALLREDUCE           mppmax_a_real 
     699#     define ROUTINE_ALLREDUCE           mppmax_a_real_sp 
     700#     include "mpp_allreduce_generic.h90" 
     701#     undef ROUTINE_ALLREDUCE 
     702#  undef DIM_1d 
     703#  undef SINGLE_PRECISION 
     704   !! 
     705   !! 
     706   !!   ----   DOUBLE PRECISION VERSIONS 
     707   !! 
     708! 
     709#  define DIM_0d 
     710#     define ROUTINE_ALLREDUCE           mppmax_real_dp 
     711#     include "mpp_allreduce_generic.h90" 
     712#     undef ROUTINE_ALLREDUCE 
     713#  undef DIM_0d 
     714#  define DIM_1d 
     715#     define ROUTINE_ALLREDUCE           mppmax_a_real_dp 
    717716#     include "mpp_allreduce_generic.h90" 
    718717#     undef ROUTINE_ALLREDUCE 
     
    739738#  undef INTEGER_TYPE 
    740739! 
     740   !! 
     741   !!   ----   SINGLE PRECISION VERSIONS 
     742   !! 
     743#  define SINGLE_PRECISION 
    741744#  define REAL_TYPE 
    742745#  define DIM_0d 
    743 #     define ROUTINE_ALLREDUCE           mppmin_real 
     746#     define ROUTINE_ALLREDUCE           mppmin_real_sp 
    744747#     include "mpp_allreduce_generic.h90" 
    745748#     undef ROUTINE_ALLREDUCE 
    746749#  undef DIM_0d 
    747750#  define DIM_1d 
    748 #     define ROUTINE_ALLREDUCE           mppmin_a_real 
     751#     define ROUTINE_ALLREDUCE           mppmin_a_real_sp 
     752#     include "mpp_allreduce_generic.h90" 
     753#     undef ROUTINE_ALLREDUCE 
     754#  undef DIM_1d 
     755#  undef SINGLE_PRECISION 
     756   !! 
     757   !!   ----   DOUBLE PRECISION VERSIONS 
     758   !! 
     759 
     760#  define DIM_0d 
     761#     define ROUTINE_ALLREDUCE           mppmin_real_dp 
     762#     include "mpp_allreduce_generic.h90" 
     763#     undef ROUTINE_ALLREDUCE 
     764#  undef DIM_0d 
     765#  define DIM_1d 
     766#     define ROUTINE_ALLREDUCE           mppmin_a_real_dp 
    749767#     include "mpp_allreduce_generic.h90" 
    750768#     undef ROUTINE_ALLREDUCE 
     
    772790#  undef DIM_1d 
    773791#  undef INTEGER_TYPE 
    774 ! 
     792 
     793   !! 
     794   !!   ----   SINGLE PRECISION VERSIONS 
     795   !! 
     796#  define OPERATION_SUM 
     797#  define SINGLE_PRECISION 
    775798#  define REAL_TYPE 
    776799#  define DIM_0d 
    777 #     define ROUTINE_ALLREDUCE           mppsum_real 
     800#     define ROUTINE_ALLREDUCE           mppsum_real_sp 
    778801#     include "mpp_allreduce_generic.h90" 
    779802#     undef ROUTINE_ALLREDUCE 
    780803#  undef DIM_0d 
    781804#  define DIM_1d 
    782 #     define ROUTINE_ALLREDUCE           mppsum_a_real 
     805#     define ROUTINE_ALLREDUCE           mppsum_a_real_sp 
     806#     include "mpp_allreduce_generic.h90" 
     807#     undef ROUTINE_ALLREDUCE 
     808#  undef DIM_1d 
     809#  undef REAL_TYPE 
     810#  undef OPERATION_SUM 
     811 
     812#  undef SINGLE_PRECISION 
     813 
     814   !! 
     815   !!   ----   DOUBLE PRECISION VERSIONS 
     816   !! 
     817#  define OPERATION_SUM 
     818#  define REAL_TYPE 
     819#  define DIM_0d 
     820#     define ROUTINE_ALLREDUCE           mppsum_real_dp 
     821#     include "mpp_allreduce_generic.h90" 
     822#     undef ROUTINE_ALLREDUCE 
     823#  undef DIM_0d 
     824#  define DIM_1d 
     825#     define ROUTINE_ALLREDUCE           mppsum_a_real_dp 
    783826#     include "mpp_allreduce_generic.h90" 
    784827#     undef ROUTINE_ALLREDUCE 
     
    807850   !!---------------------------------------------------------------------- 
    808851   !! 
     852   !! 
     853   !!   ----   SINGLE PRECISION VERSIONS 
     854   !! 
     855#  define SINGLE_PRECISION 
    809856#  define OPERATION_MINLOC 
    810857#  define DIM_2d 
    811 #     define ROUTINE_LOC           mpp_minloc2d 
     858#     define ROUTINE_LOC           mpp_minloc2d_sp 
    812859#     include "mpp_loc_generic.h90" 
    813860#     undef ROUTINE_LOC 
    814861#  undef DIM_2d 
    815862#  define DIM_3d 
    816 #     define ROUTINE_LOC           mpp_minloc3d 
     863#     define ROUTINE_LOC           mpp_minloc3d_sp 
    817864#     include "mpp_loc_generic.h90" 
    818865#     undef ROUTINE_LOC 
     
    822869#  define OPERATION_MAXLOC 
    823870#  define DIM_2d 
    824 #     define ROUTINE_LOC           mpp_maxloc2d 
     871#     define ROUTINE_LOC           mpp_maxloc2d_sp 
    825872#     include "mpp_loc_generic.h90" 
    826873#     undef ROUTINE_LOC 
    827874#  undef DIM_2d 
    828875#  define DIM_3d 
    829 #     define ROUTINE_LOC           mpp_maxloc3d 
     876#     define ROUTINE_LOC           mpp_maxloc3d_sp 
    830877#     include "mpp_loc_generic.h90" 
    831878#     undef ROUTINE_LOC 
    832879#  undef DIM_3d 
    833880#  undef OPERATION_MAXLOC 
     881#  undef SINGLE_PRECISION 
     882   !! 
     883   !!   ----   DOUBLE PRECISION VERSIONS 
     884   !! 
     885#  define OPERATION_MINLOC 
     886#  define DIM_2d 
     887#     define ROUTINE_LOC           mpp_minloc2d_dp 
     888#     include "mpp_loc_generic.h90" 
     889#     undef ROUTINE_LOC 
     890#  undef DIM_2d 
     891#  define DIM_3d 
     892#     define ROUTINE_LOC           mpp_minloc3d_dp 
     893#     include "mpp_loc_generic.h90" 
     894#     undef ROUTINE_LOC 
     895#  undef DIM_3d 
     896#  undef OPERATION_MINLOC 
     897 
     898#  define OPERATION_MAXLOC 
     899#  define DIM_2d 
     900#     define ROUTINE_LOC           mpp_maxloc2d_dp 
     901#     include "mpp_loc_generic.h90" 
     902#     undef ROUTINE_LOC 
     903#  undef DIM_2d 
     904#  define DIM_3d 
     905#     define ROUTINE_LOC           mpp_maxloc3d_dp 
     906#     include "mpp_loc_generic.h90" 
     907#     undef ROUTINE_LOC 
     908#  undef DIM_3d 
     909#  undef OPERATION_MAXLOC 
     910 
    834911 
    835912   SUBROUTINE mppsync() 
     
    843920      !!----------------------------------------------------------------------- 
    844921      ! 
     922#if defined key_mpp_mpi 
    845923      CALL mpi_barrier( mpi_comm_oce, ierror ) 
     924#endif 
    846925      ! 
    847926   END SUBROUTINE mppsync 
    848927 
    849928 
    850    SUBROUTINE mppstop( ldfinal, ld_force_abort )  
     929   SUBROUTINE mppstop( ld_abort )  
    851930      !!---------------------------------------------------------------------- 
    852931      !!                  ***  routine mppstop  *** 
     
    855934      !! 
    856935      !!---------------------------------------------------------------------- 
    857       LOGICAL, OPTIONAL, INTENT(in) :: ldfinal    ! source process number 
    858       LOGICAL, OPTIONAL, INTENT(in) :: ld_force_abort    ! source process number 
    859       LOGICAL ::   llfinal, ll_force_abort 
     936      LOGICAL, OPTIONAL, INTENT(in) :: ld_abort    ! source process number 
     937      LOGICAL ::   ll_abort 
    860938      INTEGER ::   info 
    861939      !!---------------------------------------------------------------------- 
    862       llfinal = .FALSE. 
    863       IF( PRESENT(ldfinal) ) llfinal = ldfinal 
    864       ll_force_abort = .FALSE. 
    865       IF( PRESENT(ld_force_abort) ) ll_force_abort = ld_force_abort 
    866       ! 
    867       IF(ll_force_abort) THEN 
     940      ll_abort = .FALSE. 
     941      IF( PRESENT(ld_abort) ) ll_abort = ld_abort 
     942      ! 
     943#if defined key_mpp_mpi 
     944      IF(ll_abort) THEN 
    868945         CALL mpi_abort( MPI_COMM_WORLD ) 
    869946      ELSE 
     
    871948         CALL mpi_finalize( info ) 
    872949      ENDIF 
    873       IF( .NOT. llfinal ) STOP 123456 
     950#endif 
     951      IF( ll_abort ) STOP 123 
    874952      ! 
    875953   END SUBROUTINE mppstop 
     
    883961      !!---------------------------------------------------------------------- 
    884962      ! 
     963#if defined key_mpp_mpi 
    885964      CALL MPI_COMM_FREE(kcom, ierr) 
     965#endif 
    886966      ! 
    887967   END SUBROUTINE mpp_comm_free 
     
    913993      INTEGER, ALLOCATABLE, DIMENSION(:) ::   kwork 
    914994      !!---------------------------------------------------------------------- 
     995#if defined key_mpp_mpi 
    915996      !-$$     WRITE (numout,*) 'mpp_ini_znl ', nproc, ' - ngrp_world     : ', ngrp_world 
    916997      !-$$     WRITE (numout,*) 'mpp_ini_znl ', nproc, ' - mpi_comm_world : ', mpi_comm_world 
     
    918999      ! 
    9191000      ALLOCATE( kwork(jpnij), STAT=ierr ) 
    920       IF( ierr /= 0 ) THEN 
    921          WRITE(kumout, cform_err) 
    922          WRITE(kumout,*) 'mpp_ini_znl : failed to allocate 1D array of length jpnij' 
    923          CALL mppstop 
    924       ENDIF 
     1001      IF( ierr /= 0 ) CALL ctl_stop( 'STOP', 'mpp_ini_znl : failed to allocate 1D array of length jpnij') 
    9251002 
    9261003      IF( jpnj == 1 ) THEN 
     
    9841061 
    9851062      DEALLOCATE(kwork) 
     1063#endif 
    9861064 
    9871065   END SUBROUTINE mpp_ini_znl 
     
    10151093      !!---------------------------------------------------------------------- 
    10161094      ! 
     1095#if defined key_mpp_mpi 
    10171096      njmppmax = MAXVAL( njmppt ) 
    10181097      ! 
    10191098      ! Look for how many procs on the northern boundary 
    10201099      ndim_rank_north = 0 
    1021       DO jjproc = 1, jpnij 
    1022          IF( njmppt(jjproc) == njmppmax )   ndim_rank_north = ndim_rank_north + 1 
     1100      DO jjproc = 1, jpni 
     1101         IF( nfproc(jjproc) /= -1 )   ndim_rank_north = ndim_rank_north + 1 
    10231102      END DO 
    10241103      ! 
     
    10301109      ! Note : the rank start at 0 in MPI 
    10311110      ii = 0 
    1032       DO ji = 1, jpnij 
    1033          IF ( njmppt(ji) == njmppmax   ) THEN 
     1111      DO ji = 1, jpni 
     1112         IF ( nfproc(ji) /= -1   ) THEN 
    10341113            ii=ii+1 
    1035             nrank_north(ii)=ji-1 
     1114            nrank_north(ii)=nfproc(ji) 
    10361115         END IF 
    10371116      END DO 
     
    10461125      CALL MPI_COMM_CREATE( mpi_comm_oce, ngrp_north, ncomm_north, ierr ) 
    10471126      ! 
     1127#endif 
    10481128   END SUBROUTINE mpp_ini_north 
    1049  
    1050  
    1051    SUBROUTINE mpi_init_oce( ldtxt, ksft, code ) 
    1052       !!--------------------------------------------------------------------- 
    1053       !!                   ***  routine mpp_init.opa  *** 
    1054       !! 
    1055       !! ** Purpose :: export and attach a MPI buffer for bsend 
    1056       !! 
    1057       !! ** Method  :: define buffer size in namelist, if 0 no buffer attachment 
    1058       !!            but classical mpi_init 
    1059       !! 
    1060       !! History :: 01/11 :: IDRIS initial version for IBM only 
    1061       !!            08/04 :: R. Benshila, generalisation 
    1062       !!--------------------------------------------------------------------- 
    1063       CHARACTER(len=*),DIMENSION(:), INTENT(  out) ::   ldtxt 
    1064       INTEGER                      , INTENT(inout) ::   ksft 
    1065       INTEGER                      , INTENT(  out) ::   code 
    1066       INTEGER                                      ::   ierr, ji 
    1067       LOGICAL                                      ::   mpi_was_called 
    1068       !!--------------------------------------------------------------------- 
    1069       ! 
    1070       CALL mpi_initialized( mpi_was_called, code )      ! MPI initialization 
    1071       IF ( code /= MPI_SUCCESS ) THEN 
    1072          DO ji = 1, SIZE(ldtxt) 
    1073             IF( TRIM(ldtxt(ji)) /= '' )   WRITE(*,*) ldtxt(ji)      ! control print of mynode 
    1074          END DO 
    1075          WRITE(*, cform_err) 
    1076          WRITE(*, *) ' lib_mpp: Error in routine mpi_initialized' 
    1077          CALL mpi_abort( mpi_comm_world, code, ierr ) 
    1078       ENDIF 
    1079       ! 
    1080       IF( .NOT. mpi_was_called ) THEN 
    1081          CALL mpi_init( code ) 
    1082          CALL mpi_comm_dup( mpi_comm_world, mpi_comm_oce, code ) 
    1083          IF ( code /= MPI_SUCCESS ) THEN 
    1084             DO ji = 1, SIZE(ldtxt) 
    1085                IF( TRIM(ldtxt(ji)) /= '' )   WRITE(*,*) ldtxt(ji)      ! control print of mynode 
    1086             END DO 
    1087             WRITE(*, cform_err) 
    1088             WRITE(*, *) ' lib_mpp: Error in routine mpi_comm_dup' 
    1089             CALL mpi_abort( mpi_comm_world, code, ierr ) 
    1090          ENDIF 
    1091       ENDIF 
    1092       ! 
    1093       IF( nn_buffer > 0 ) THEN 
    1094          WRITE(ldtxt(ksft),*) 'mpi_bsend, buffer allocation of  : ', nn_buffer   ;   ksft = ksft + 1 
    1095          ! Buffer allocation and attachment 
    1096          ALLOCATE( tampon(nn_buffer), stat = ierr ) 
    1097          IF( ierr /= 0 ) THEN 
    1098             DO ji = 1, SIZE(ldtxt) 
    1099                IF( TRIM(ldtxt(ji)) /= '' )   WRITE(*,*) ldtxt(ji)      ! control print of mynode 
    1100             END DO 
    1101             WRITE(*, cform_err) 
    1102             WRITE(*, *) ' lib_mpp: Error in ALLOCATE', ierr 
    1103             CALL mpi_abort( mpi_comm_world, code, ierr ) 
    1104          END IF 
    1105          CALL mpi_buffer_attach( tampon, nn_buffer, code ) 
    1106       ENDIF 
    1107       ! 
    1108    END SUBROUTINE mpi_init_oce 
    11091129 
    11101130 
     
    11171137      !!--------------------------------------------------------------------- 
    11181138      INTEGER                     , INTENT(in)    ::   ilen, itype 
    1119       COMPLEX(wp), DIMENSION(ilen), INTENT(in)    ::   ydda 
    1120       COMPLEX(wp), DIMENSION(ilen), INTENT(inout) ::   yddb 
    1121       ! 
    1122       REAL(wp) :: zerr, zt1, zt2    ! local work variables 
     1139      COMPLEX(dp), DIMENSION(ilen), INTENT(in)    ::   ydda 
     1140      COMPLEX(dp), DIMENSION(ilen), INTENT(inout) ::   yddb 
     1141      ! 
     1142      REAL(dp) :: zerr, zt1, zt2    ! local work variables 
    11231143      INTEGER  :: ji, ztmp           ! local scalar 
    11241144      !!--------------------------------------------------------------------- 
     
    11401160 
    11411161 
    1142    SUBROUTINE mpp_lbc_north_icb( pt2d, cd_type, psgn, kextj) 
    1143       !!--------------------------------------------------------------------- 
    1144       !!                   ***  routine mpp_lbc_north_icb  *** 
    1145       !! 
    1146       !! ** Purpose :   Ensure proper north fold horizontal bondary condition 
    1147       !!              in mpp configuration in case of jpn1 > 1 and for 2d 
    1148       !!              array with outer extra halo 
    1149       !! 
    1150       !! ** Method  :   North fold condition and mpp with more than one proc 
    1151       !!              in i-direction require a specific treatment. We gather 
    1152       !!              the 4+kextj northern lines of the global domain on 1 
    1153       !!              processor and apply lbc north-fold on this sub array. 
    1154       !!              Then we scatter the north fold array back to the processors. 
    1155       !!              This routine accounts for an extra halo with icebergs 
    1156       !!              and assumes ghost rows and columns have been suppressed. 
    1157       !! 
    1158       !!---------------------------------------------------------------------- 
    1159       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d     ! 2D array with extra halo 
    1160       CHARACTER(len=1)        , INTENT(in   ) ::   cd_type  ! nature of pt3d grid-points 
    1161       !                                                     !   = T ,  U , V , F or W -points 
    1162       REAL(wp)                , INTENT(in   ) ::   psgn     ! = -1. the sign change across the 
    1163       !!                                                    ! north fold, =  1. otherwise 
    1164       INTEGER                 , INTENT(in   ) ::   kextj    ! Extra halo width at north fold 
    1165       ! 
    1166       INTEGER ::   ji, jj, jr 
    1167       INTEGER ::   ierr, itaille, ildi, ilei, iilb 
    1168       INTEGER ::   ipj, ij, iproc 
    1169       ! 
    1170       REAL(wp), DIMENSION(:,:)  , ALLOCATABLE  ::  ztab_e, znorthloc_e 
    1171       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE  ::  znorthgloio_e 
    1172       !!---------------------------------------------------------------------- 
    1173       ! 
    1174       ipj=4 
    1175       ALLOCATE(        ztab_e(jpiglo, 1-kextj:ipj+kextj)       ,       & 
    1176      &            znorthloc_e(jpimax, 1-kextj:ipj+kextj)       ,       & 
    1177      &          znorthgloio_e(jpimax, 1-kextj:ipj+kextj,jpni)    ) 
    1178       ! 
    1179       ztab_e(:,:)      = 0._wp 
    1180       znorthloc_e(:,:) = 0._wp 
    1181       ! 
    1182       ij = 1 - kextj 
    1183       ! put the last ipj+2*kextj lines of pt2d into znorthloc_e  
    1184       DO jj = jpj - ipj + 1 - kextj , jpj + kextj 
    1185          znorthloc_e(1:jpi,ij)=pt2d(1:jpi,jj) 
    1186          ij = ij + 1 
    1187       END DO 
    1188       ! 
    1189       itaille = jpimax * ( ipj + 2*kextj ) 
    1190       ! 
    1191       CALL MPI_ALLGATHER( znorthloc_e(1,1-kextj)    , itaille, MPI_DOUBLE_PRECISION,    & 
    1192          &                znorthgloio_e(1,1-kextj,1), itaille, MPI_DOUBLE_PRECISION,    & 
    1193          &                ncomm_north, ierr ) 
    1194       ! 
    1195       ! 
    1196       DO jr = 1, ndim_rank_north            ! recover the global north array 
    1197          iproc = nrank_north(jr) + 1 
    1198          ildi = nldit (iproc) 
    1199          ilei = nleit (iproc) 
    1200          iilb = nimppt(iproc) 
    1201          DO jj = 1-kextj, ipj+kextj 
    1202             DO ji = ildi, ilei 
    1203                ztab_e(ji+iilb-1,jj) = znorthgloio_e(ji,jj,jr) 
    1204             END DO 
    1205          END DO 
    1206       END DO 
    1207  
    1208       ! 2. North-Fold boundary conditions 
    1209       ! ---------------------------------- 
    1210       CALL lbc_nfd( ztab_e(:,1-kextj:ipj+kextj), cd_type, psgn, kextj ) 
    1211  
    1212       ij = 1 - kextj 
    1213       !! Scatter back to pt2d 
    1214       DO jj = jpj - ipj + 1 - kextj , jpj + kextj 
    1215          DO ji= 1, jpi 
    1216             pt2d(ji,jj) = ztab_e(ji+nimpp-1,ij) 
    1217          END DO 
    1218          ij  = ij +1 
    1219       END DO 
    1220       ! 
    1221       DEALLOCATE( ztab_e, znorthloc_e, znorthgloio_e ) 
    1222       ! 
    1223    END SUBROUTINE mpp_lbc_north_icb 
    1224  
    1225  
    1226    SUBROUTINE mpp_lnk_2d_icb( cdname, pt2d, cd_type, psgn, kexti, kextj ) 
    1227       !!---------------------------------------------------------------------- 
    1228       !!                  ***  routine mpp_lnk_2d_icb  *** 
    1229       !! 
    1230       !! ** Purpose :   Message passing management for 2d array (with extra halo for icebergs) 
    1231       !!                This routine receives a (1-kexti:jpi+kexti,1-kexti:jpj+kextj) 
    1232       !!                array (usually (0:jpi+1, 0:jpj+1)) from lbc_lnk_icb calls. 
    1233       !! 
    1234       !! ** Method  :   Use mppsend and mpprecv function for passing mask 
    1235       !!      between processors following neighboring subdomains. 
    1236       !!            domain parameters 
    1237       !!                    jpi    : first dimension of the local subdomain 
    1238       !!                    jpj    : second dimension of the local subdomain 
    1239       !!                    kexti  : number of columns for extra outer halo 
    1240       !!                    kextj  : number of rows for extra outer halo 
    1241       !!                    nbondi : mark for "east-west local boundary" 
    1242       !!                    nbondj : mark for "north-south local boundary" 
    1243       !!                    noea   : number for local neighboring processors 
    1244       !!                    nowe   : number for local neighboring processors 
    1245       !!                    noso   : number for local neighboring processors 
    1246       !!                    nono   : number for local neighboring processors 
    1247       !!---------------------------------------------------------------------- 
    1248       CHARACTER(len=*)                                        , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
    1249       REAL(wp), DIMENSION(1-kexti:jpi+kexti,1-kextj:jpj+kextj), INTENT(inout) ::   pt2d     ! 2D array with extra halo 
    1250       CHARACTER(len=1)                                        , INTENT(in   ) ::   cd_type  ! nature of ptab array grid-points 
    1251       REAL(wp)                                                , INTENT(in   ) ::   psgn     ! sign used across the north fold 
    1252       INTEGER                                                 , INTENT(in   ) ::   kexti    ! extra i-halo width 
    1253       INTEGER                                                 , INTENT(in   ) ::   kextj    ! extra j-halo width 
    1254       ! 
    1255       INTEGER  ::   jl   ! dummy loop indices 
    1256       INTEGER  ::   imigr, iihom, ijhom        ! local integers 
    1257       INTEGER  ::   ipreci, iprecj             !   -       - 
    1258       INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend 
    1259       INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend 
    1260       !! 
    1261       REAL(wp), DIMENSION(1-kexti:jpi+kexti,nn_hls+kextj,2) ::   r2dns, r2dsn 
    1262       REAL(wp), DIMENSION(1-kextj:jpj+kextj,nn_hls+kexti,2) ::   r2dwe, r2dew 
    1263       !!---------------------------------------------------------------------- 
    1264  
    1265       ipreci = nn_hls + kexti      ! take into account outer extra 2D overlap area 
    1266       iprecj = nn_hls + kextj 
    1267  
    1268       IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, 1, 1, 1, ld_lbc = .TRUE. ) 
    1269  
    1270       ! 1. standard boundary treatment 
    1271       ! ------------------------------ 
    1272       ! Order matters Here !!!! 
    1273       ! 
    1274       !                                      ! East-West boundaries 
    1275       !                                           !* Cyclic east-west 
    1276       IF( l_Iperio ) THEN 
    1277          pt2d(1-kexti:     1   ,:) = pt2d(jpim1-kexti: jpim1 ,:)       ! east 
    1278          pt2d(  jpi  :jpi+kexti,:) = pt2d(     2     :2+kexti,:)       ! west 
    1279          ! 
    1280       ELSE                                        !* closed 
    1281          IF( .NOT. cd_type == 'F' )   pt2d(  1-kexti   :nn_hls   ,:) = 0._wp    ! east except at F-point 
    1282                                       pt2d(jpi-nn_hls+1:jpi+kexti,:) = 0._wp    ! west 
    1283       ENDIF 
    1284       !                                      ! North-South boundaries 
    1285       IF( l_Jperio ) THEN                         !* cyclic (only with no mpp j-split) 
    1286          pt2d(:,1-kextj:     1   ) = pt2d(:,jpjm1-kextj:  jpjm1)       ! north 
    1287          pt2d(:,  jpj  :jpj+kextj) = pt2d(:,     2     :2+kextj)       ! south 
    1288       ELSE                                        !* closed 
    1289          IF( .NOT. cd_type == 'F' )   pt2d(:,  1-kextj   :nn_hls   ) = 0._wp    ! north except at F-point 
    1290                                       pt2d(:,jpj-nn_hls+1:jpj+kextj) = 0._wp    ! south 
    1291       ENDIF 
    1292       ! 
    1293  
    1294       ! north fold treatment 
    1295       ! ----------------------- 
    1296       IF( npolj /= 0 ) THEN 
    1297          ! 
    1298          SELECT CASE ( jpni ) 
    1299                    CASE ( 1 )     ;   CALL lbc_nfd          ( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj ) 
    1300                    CASE DEFAULT   ;   CALL mpp_lbc_north_icb( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj ) 
    1301          END SELECT 
    1302          ! 
    1303       ENDIF 
    1304  
    1305       ! 2. East and west directions exchange 
    1306       ! ------------------------------------ 
    1307       ! we play with the neigbours AND the row number because of the periodicity 
    1308       ! 
    1309       SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
    1310       CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case) 
    1311          iihom = jpi-nreci-kexti 
    1312          DO jl = 1, ipreci 
    1313             r2dew(:,jl,1) = pt2d(nn_hls+jl,:) 
    1314             r2dwe(:,jl,1) = pt2d(iihom +jl,:) 
    1315          END DO 
    1316       END SELECT 
    1317       ! 
    1318       !                           ! Migrations 
    1319       imigr = ipreci * ( jpj + 2*kextj ) 
    1320       ! 
    1321       SELECT CASE ( nbondi ) 
    1322       CASE ( -1 ) 
    1323          CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req1 ) 
    1324          CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea ) 
    1325          IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    1326       CASE ( 0 ) 
    1327          CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 ) 
    1328          CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req2 ) 
    1329          CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea ) 
    1330          CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe ) 
    1331          IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    1332          IF(l_isend) CALL mpi_wait(ml_req2,ml_stat,ml_err) 
    1333       CASE ( 1 ) 
    1334          CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 ) 
    1335          CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe ) 
    1336          IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    1337       END SELECT 
    1338       ! 
    1339       !                           ! Write Dirichlet lateral conditions 
    1340       iihom = jpi - nn_hls 
    1341       ! 
    1342       SELECT CASE ( nbondi ) 
    1343       CASE ( -1 ) 
    1344          DO jl = 1, ipreci 
    1345             pt2d(iihom+jl,:) = r2dew(:,jl,2) 
    1346          END DO 
    1347       CASE ( 0 ) 
    1348          DO jl = 1, ipreci 
    1349             pt2d(jl-kexti,:) = r2dwe(:,jl,2) 
    1350             pt2d(iihom+jl,:) = r2dew(:,jl,2) 
    1351          END DO 
    1352       CASE ( 1 ) 
    1353          DO jl = 1, ipreci 
    1354             pt2d(jl-kexti,:) = r2dwe(:,jl,2) 
    1355          END DO 
    1356       END SELECT 
    1357  
    1358  
    1359       ! 3. North and south directions 
    1360       ! ----------------------------- 
    1361       ! always closed : we play only with the neigbours 
    1362       ! 
    1363       IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions 
    1364          ijhom = jpj-nrecj-kextj 
    1365          DO jl = 1, iprecj 
    1366             r2dsn(:,jl,1) = pt2d(:,ijhom +jl) 
    1367             r2dns(:,jl,1) = pt2d(:,nn_hls+jl) 
    1368          END DO 
    1369       ENDIF 
    1370       ! 
    1371       !                           ! Migrations 
    1372       imigr = iprecj * ( jpi + 2*kexti ) 
    1373       ! 
    1374       SELECT CASE ( nbondj ) 
    1375       CASE ( -1 ) 
    1376          CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req1 ) 
    1377          CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono ) 
    1378          IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    1379       CASE ( 0 ) 
    1380          CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 ) 
    1381          CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req2 ) 
    1382          CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono ) 
    1383          CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso ) 
    1384          IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    1385          IF(l_isend) CALL mpi_wait(ml_req2,ml_stat,ml_err) 
    1386       CASE ( 1 ) 
    1387          CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 ) 
    1388          CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso ) 
    1389          IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err) 
    1390       END SELECT 
    1391       ! 
    1392       !                           ! Write Dirichlet lateral conditions 
    1393       ijhom = jpj - nn_hls 
    1394       ! 
    1395       SELECT CASE ( nbondj ) 
    1396       CASE ( -1 ) 
    1397          DO jl = 1, iprecj 
    1398             pt2d(:,ijhom+jl) = r2dns(:,jl,2) 
    1399          END DO 
    1400       CASE ( 0 ) 
    1401          DO jl = 1, iprecj 
    1402             pt2d(:,jl-kextj) = r2dsn(:,jl,2) 
    1403             pt2d(:,ijhom+jl) = r2dns(:,jl,2) 
    1404          END DO 
    1405       CASE ( 1 ) 
    1406          DO jl = 1, iprecj 
    1407             pt2d(:,jl-kextj) = r2dsn(:,jl,2) 
    1408          END DO 
    1409       END SELECT 
    1410       ! 
    1411    END SUBROUTINE mpp_lnk_2d_icb 
    1412  
    1413  
    14141162   SUBROUTINE mpp_report( cdname, kpk, kpl, kpf, ld_lbc, ld_glb, ld_dlg ) 
    14151163      !!---------------------------------------------------------------------- 
     
    14231171      LOGICAL         , OPTIONAL, INTENT(in   ) ::   ld_lbc, ld_glb, ld_dlg 
    14241172      !! 
     1173      CHARACTER(len=128)                        ::   ccountname  ! name of a subroutine to count communications 
    14251174      LOGICAL ::   ll_lbc, ll_glb, ll_dlg 
    1426       INTEGER ::    ji,  jj,  jk,  jh, jf   ! dummy loop indices 
    1427       !!---------------------------------------------------------------------- 
     1175      INTEGER ::    ji,  jj,  jk,  jh, jf, jcount   ! dummy loop indices 
     1176      !!---------------------------------------------------------------------- 
     1177#if defined key_mpp_mpi 
    14281178      ! 
    14291179      ll_lbc = .FALSE. 
     
    14351185      ! 
    14361186      ! find the smallest common frequency: default = frequency product, if multiple, choose the larger of the 2 frequency 
    1437       IF( ncom_dttrc /= 1 )   CALL ctl_stop( 'STOP', 'mpp_report, ncom_dttrc /= 1 not coded...' )  
    14381187      ncom_freq = ncom_fsbc 
    14391188      ! 
     
    14811230         WRITE(numcom,*) ' ' 
    14821231         WRITE(numcom,*) ' lbc_lnk called' 
    1483          jj = 1 
    1484          DO ji = 2, n_sequence_lbc 
    1485             IF( crname_lbc(ji-1) /= crname_lbc(ji) ) THEN 
    1486                WRITE(numcom,'(A, I4, A, A)') ' - ', jj,' times by subroutine ', TRIM(crname_lbc(ji-1)) 
    1487                jj = 0 
     1232         DO ji = 1, n_sequence_lbc - 1 
     1233            IF ( crname_lbc(ji) /= 'already counted' ) THEN 
     1234               ccountname = crname_lbc(ji) 
     1235               crname_lbc(ji) = 'already counted' 
     1236               jcount = 1 
     1237               DO jj = ji + 1, n_sequence_lbc 
     1238                  IF ( ccountname ==  crname_lbc(jj) ) THEN 
     1239                     jcount = jcount + 1 
     1240                     crname_lbc(jj) = 'already counted' 
     1241                  END IF 
     1242               END DO 
     1243               WRITE(numcom,'(A, I4, A, A)') ' - ', jcount,' times by subroutine ', TRIM(ccountname) 
    14881244            END IF 
    1489             jj = jj + 1  
    14901245         END DO 
    1491          WRITE(numcom,'(A, I4, A, A)') ' - ', jj,' times by subroutine ', TRIM(crname_lbc(n_sequence_lbc)) 
     1246         IF ( crname_lbc(n_sequence_lbc) /= 'already counted' ) THEN 
     1247            WRITE(numcom,'(A, I4, A, A)') ' - ', 1,' times by subroutine ', TRIM(crname_lbc(ncom_rec_max)) 
     1248         END IF 
    14921249         WRITE(numcom,*) ' ' 
    14931250         IF ( n_sequence_glb > 0 ) THEN 
     
    15281285         DEALLOCATE(crname_lbc) 
    15291286      ENDIF 
     1287#endif 
    15301288   END SUBROUTINE mpp_report 
     1289 
    15311290    
    1532 #else 
    1533    !!---------------------------------------------------------------------- 
    1534    !!   Default case:            Dummy module        share memory computing 
    1535    !!---------------------------------------------------------------------- 
    1536    USE in_out_manager 
    1537  
    1538    INTERFACE mpp_sum 
    1539       MODULE PROCEDURE mppsum_int, mppsum_a_int, mppsum_real, mppsum_a_real, mppsum_realdd, mppsum_a_realdd 
    1540    END INTERFACE 
    1541    INTERFACE mpp_max 
    1542       MODULE PROCEDURE mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real 
    1543    END INTERFACE 
    1544    INTERFACE mpp_min 
    1545       MODULE PROCEDURE mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real 
    1546    END INTERFACE 
    1547    INTERFACE mpp_minloc 
    1548       MODULE PROCEDURE mpp_minloc2d ,mpp_minloc3d 
    1549    END INTERFACE 
    1550    INTERFACE mpp_maxloc 
    1551       MODULE PROCEDURE mpp_maxloc2d ,mpp_maxloc3d 
    1552    END INTERFACE 
    1553  
    1554    LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .FALSE.      !: mpp flag 
    1555    LOGICAL, PUBLIC            ::   ln_nnogather          !: namelist control of northfold comms (needed here in case "key_mpp_mpi" is not used) 
    1556    INTEGER, PUBLIC            ::   mpi_comm_oce          ! opa local communicator 
    1557  
    1558    INTEGER, PARAMETER, PUBLIC               ::   nbdelay = 0   ! make sure we don't enter loops: DO ji = 1, nbdelay 
    1559    CHARACTER(len=32), DIMENSION(1), PUBLIC  ::   c_delaylist = 'empty' 
    1560    CHARACTER(len=32), DIMENSION(1), PUBLIC  ::   c_delaycpnt = 'empty' 
    1561    LOGICAL, PUBLIC                          ::   l_full_nf_update = .TRUE. 
    1562    TYPE ::   DELAYARR 
    1563       REAL(   wp), POINTER, DIMENSION(:) ::  z1d => NULL() 
    1564       COMPLEX(wp), POINTER, DIMENSION(:) ::  y1d => NULL() 
    1565    END TYPE DELAYARR 
    1566    TYPE( DELAYARR ), DIMENSION(1), PUBLIC  ::   todelay               
    1567    INTEGER,  PUBLIC, DIMENSION(1)           ::   ndelayid = -1 
    1568    !!---------------------------------------------------------------------- 
    1569 CONTAINS 
    1570  
    1571    INTEGER FUNCTION lib_mpp_alloc(kumout)          ! Dummy function 
    1572       INTEGER, INTENT(in) ::   kumout 
    1573       lib_mpp_alloc = 0 
    1574    END FUNCTION lib_mpp_alloc 
    1575  
    1576    FUNCTION mynode( ldtxt, ldname, kumnam_ref, knumnam_cfg,  kumond , kstop, localComm ) RESULT (function_value) 
    1577       INTEGER, OPTIONAL            , INTENT(in   ) ::   localComm 
    1578       CHARACTER(len=*),DIMENSION(:) ::   ldtxt 
    1579       CHARACTER(len=*) ::   ldname 
    1580       INTEGER ::   kumnam_ref, knumnam_cfg , kumond , kstop 
    1581       IF( PRESENT( localComm ) ) mpi_comm_oce = localComm 
    1582       function_value = 0 
    1583       IF( .FALSE. )   ldtxt(:) = 'never done' 
    1584       CALL ctl_opn( kumond, TRIM(ldname), 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. , 1 ) 
    1585    END FUNCTION mynode 
    1586  
    1587    SUBROUTINE mppsync                       ! Dummy routine 
    1588    END SUBROUTINE mppsync 
    1589  
    1590    !!---------------------------------------------------------------------- 
    1591    !!    ***  mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real  *** 
    1592    !!    
    1593    !!---------------------------------------------------------------------- 
    1594    !! 
    1595 #  define OPERATION_MAX 
    1596 #  define INTEGER_TYPE 
    1597 #  define DIM_0d 
    1598 #     define ROUTINE_ALLREDUCE           mppmax_int 
    1599 #     include "mpp_allreduce_generic.h90" 
    1600 #     undef ROUTINE_ALLREDUCE 
    1601 #  undef DIM_0d 
    1602 #  define DIM_1d 
    1603 #     define ROUTINE_ALLREDUCE           mppmax_a_int 
    1604 #     include "mpp_allreduce_generic.h90" 
    1605 #     undef ROUTINE_ALLREDUCE 
    1606 #  undef DIM_1d 
    1607 #  undef INTEGER_TYPE 
    1608 ! 
    1609 #  define REAL_TYPE 
    1610 #  define DIM_0d 
    1611 #     define ROUTINE_ALLREDUCE           mppmax_real 
    1612 #     include "mpp_allreduce_generic.h90" 
    1613 #     undef ROUTINE_ALLREDUCE 
    1614 #  undef DIM_0d 
    1615 #  define DIM_1d 
    1616 #     define ROUTINE_ALLREDUCE           mppmax_a_real 
    1617 #     include "mpp_allreduce_generic.h90" 
    1618 #     undef ROUTINE_ALLREDUCE 
    1619 #  undef DIM_1d 
    1620 #  undef REAL_TYPE 
    1621 #  undef OPERATION_MAX 
    1622    !!---------------------------------------------------------------------- 
    1623    !!    ***  mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real  *** 
    1624    !!    
    1625    !!---------------------------------------------------------------------- 
    1626    !! 
    1627 #  define OPERATION_MIN 
    1628 #  define INTEGER_TYPE 
    1629 #  define DIM_0d 
    1630 #     define ROUTINE_ALLREDUCE           mppmin_int 
    1631 #     include "mpp_allreduce_generic.h90" 
    1632 #     undef ROUTINE_ALLREDUCE 
    1633 #  undef DIM_0d 
    1634 #  define DIM_1d 
    1635 #     define ROUTINE_ALLREDUCE           mppmin_a_int 
    1636 #     include "mpp_allreduce_generic.h90" 
    1637 #     undef ROUTINE_ALLREDUCE 
    1638 #  undef DIM_1d 
    1639 #  undef INTEGER_TYPE 
    1640 ! 
    1641 #  define REAL_TYPE 
    1642 #  define DIM_0d 
    1643 #     define ROUTINE_ALLREDUCE           mppmin_real 
    1644 #     include "mpp_allreduce_generic.h90" 
    1645 #     undef ROUTINE_ALLREDUCE 
    1646 #  undef DIM_0d 
    1647 #  define DIM_1d 
    1648 #     define ROUTINE_ALLREDUCE           mppmin_a_real 
    1649 #     include "mpp_allreduce_generic.h90" 
    1650 #     undef ROUTINE_ALLREDUCE 
    1651 #  undef DIM_1d 
    1652 #  undef REAL_TYPE 
    1653 #  undef OPERATION_MIN 
    1654  
    1655    !!---------------------------------------------------------------------- 
    1656    !!    ***  mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real  *** 
    1657    !!    
    1658    !!   Global sum of 1D array or a variable (integer, real or complex) 
    1659    !!---------------------------------------------------------------------- 
    1660    !! 
    1661 #  define OPERATION_SUM 
    1662 #  define INTEGER_TYPE 
    1663 #  define DIM_0d 
    1664 #     define ROUTINE_ALLREDUCE           mppsum_int 
    1665 #     include "mpp_allreduce_generic.h90" 
    1666 #     undef ROUTINE_ALLREDUCE 
    1667 #  undef DIM_0d 
    1668 #  define DIM_1d 
    1669 #     define ROUTINE_ALLREDUCE           mppsum_a_int 
    1670 #     include "mpp_allreduce_generic.h90" 
    1671 #     undef ROUTINE_ALLREDUCE 
    1672 #  undef DIM_1d 
    1673 #  undef INTEGER_TYPE 
    1674 ! 
    1675 #  define REAL_TYPE 
    1676 #  define DIM_0d 
    1677 #     define ROUTINE_ALLREDUCE           mppsum_real 
    1678 #     include "mpp_allreduce_generic.h90" 
    1679 #     undef ROUTINE_ALLREDUCE 
    1680 #  undef DIM_0d 
    1681 #  define DIM_1d 
    1682 #     define ROUTINE_ALLREDUCE           mppsum_a_real 
    1683 #     include "mpp_allreduce_generic.h90" 
    1684 #     undef ROUTINE_ALLREDUCE 
    1685 #  undef DIM_1d 
    1686 #  undef REAL_TYPE 
    1687 #  undef OPERATION_SUM 
    1688  
    1689 #  define OPERATION_SUM_DD 
    1690 #  define COMPLEX_TYPE 
    1691 #  define DIM_0d 
    1692 #     define ROUTINE_ALLREDUCE           mppsum_realdd 
    1693 #     include "mpp_allreduce_generic.h90" 
    1694 #     undef ROUTINE_ALLREDUCE 
    1695 #  undef DIM_0d 
    1696 #  define DIM_1d 
    1697 #     define ROUTINE_ALLREDUCE           mppsum_a_realdd 
    1698 #     include "mpp_allreduce_generic.h90" 
    1699 #     undef ROUTINE_ALLREDUCE 
    1700 #  undef DIM_1d 
    1701 #  undef COMPLEX_TYPE 
    1702 #  undef OPERATION_SUM_DD 
    1703  
    1704    !!---------------------------------------------------------------------- 
    1705    !!    ***  mpp_minloc2d, mpp_minloc3d, mpp_maxloc2d, mpp_maxloc3d 
    1706    !!    
    1707    !!---------------------------------------------------------------------- 
    1708    !! 
    1709 #  define OPERATION_MINLOC 
    1710 #  define DIM_2d 
    1711 #     define ROUTINE_LOC           mpp_minloc2d 
    1712 #     include "mpp_loc_generic.h90" 
    1713 #     undef ROUTINE_LOC 
    1714 #  undef DIM_2d 
    1715 #  define DIM_3d 
    1716 #     define ROUTINE_LOC           mpp_minloc3d 
    1717 #     include "mpp_loc_generic.h90" 
    1718 #     undef ROUTINE_LOC 
    1719 #  undef DIM_3d 
    1720 #  undef OPERATION_MINLOC 
    1721  
    1722 #  define OPERATION_MAXLOC 
    1723 #  define DIM_2d 
    1724 #     define ROUTINE_LOC           mpp_maxloc2d 
    1725 #     include "mpp_loc_generic.h90" 
    1726 #     undef ROUTINE_LOC 
    1727 #  undef DIM_2d 
    1728 #  define DIM_3d 
    1729 #     define ROUTINE_LOC           mpp_maxloc3d 
    1730 #     include "mpp_loc_generic.h90" 
    1731 #     undef ROUTINE_LOC 
    1732 #  undef DIM_3d 
    1733 #  undef OPERATION_MAXLOC 
    1734  
    1735    SUBROUTINE mpp_delay_sum( cdname, cdelay, y_in, pout, ldlast, kcom ) 
    1736       CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine 
    1737       CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation 
    1738       COMPLEX(wp),      INTENT(in   ), DIMENSION(:) ::   y_in 
    1739       REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout 
    1740       LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine 
    1741       INTEGER,          INTENT(in   ), OPTIONAL     ::   kcom 
    1742       ! 
    1743       pout(:) = REAL(y_in(:), wp) 
    1744    END SUBROUTINE mpp_delay_sum 
    1745  
    1746    SUBROUTINE mpp_delay_max( cdname, cdelay, p_in, pout, ldlast, kcom ) 
    1747       CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine 
    1748       CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation 
    1749       REAL(wp),         INTENT(in   ), DIMENSION(:) ::   p_in 
    1750       REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout 
    1751       LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine 
    1752       INTEGER,          INTENT(in   ), OPTIONAL     ::   kcom 
    1753       ! 
    1754       pout(:) = p_in(:) 
    1755    END SUBROUTINE mpp_delay_max 
    1756  
    1757    SUBROUTINE mpp_delay_rcv( kid ) 
    1758       INTEGER,INTENT(in   )      ::  kid  
    1759       WRITE(*,*) 'mpp_delay_rcv: You should not have seen this print! error?', kid 
    1760    END SUBROUTINE mpp_delay_rcv 
     1291   SUBROUTINE tic_tac (ld_tic, ld_global) 
     1292 
     1293    LOGICAL,           INTENT(IN) :: ld_tic 
     1294    LOGICAL, OPTIONAL, INTENT(IN) :: ld_global 
     1295    REAL(dp), DIMENSION(2), SAVE :: tic_wt 
     1296    REAL(dp),               SAVE :: tic_ct = 0._dp 
     1297    INTEGER :: ii 
     1298#if defined key_mpp_mpi 
     1299 
     1300    IF( ncom_stp <= nit000 ) RETURN 
     1301    IF( ncom_stp == nitend ) RETURN 
     1302    ii = 1 
     1303    IF( PRESENT( ld_global ) ) THEN 
     1304       IF( ld_global ) ii = 2 
     1305    END IF 
     1306     
     1307    IF ( ld_tic ) THEN 
     1308       tic_wt(ii) = MPI_Wtime()                                                    ! start count tic->tac (waiting time) 
     1309       IF ( tic_ct > 0.0_dp ) compute_time = compute_time + MPI_Wtime() - tic_ct   ! cumulate count tac->tic 
     1310    ELSE 
     1311       waiting_time(ii) = waiting_time(ii) + MPI_Wtime() - tic_wt(ii)              ! cumulate count tic->tac 
     1312       tic_ct = MPI_Wtime()                                                        ! start count tac->tic (waiting time) 
     1313    ENDIF 
     1314#endif 
     1315     
     1316   END SUBROUTINE tic_tac 
     1317 
     1318#if ! defined key_mpp_mpi 
     1319   SUBROUTINE mpi_wait(request, status, ierror) 
     1320      INTEGER                            , INTENT(in   ) ::   request 
     1321      INTEGER, DIMENSION(MPI_STATUS_SIZE), INTENT(  out) ::   status 
     1322      INTEGER                            , INTENT(  out) ::   ierror 
     1323   END SUBROUTINE mpi_wait 
     1324 
    17611325    
    1762    SUBROUTINE mppstop( ldfinal, ld_force_abort ) 
    1763       LOGICAL, OPTIONAL, INTENT(in) :: ldfinal    ! source process number 
    1764       LOGICAL, OPTIONAL, INTENT(in) :: ld_force_abort    ! source process number 
    1765       STOP      ! non MPP case, just stop the run 
    1766    END SUBROUTINE mppstop 
    1767  
    1768    SUBROUTINE mpp_ini_znl( knum ) 
    1769       INTEGER :: knum 
    1770       WRITE(*,*) 'mpp_ini_znl: You should not have seen this print! error?', knum 
    1771    END SUBROUTINE mpp_ini_znl 
    1772  
    1773    SUBROUTINE mpp_comm_free( kcom ) 
    1774       INTEGER :: kcom 
    1775       WRITE(*,*) 'mpp_comm_free: You should not have seen this print! error?', kcom 
    1776    END SUBROUTINE mpp_comm_free 
    1777     
    1778 #endif 
    1779  
    1780    !!---------------------------------------------------------------------- 
    1781    !!   All cases:         ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam   routines 
     1326   FUNCTION MPI_Wtime() 
     1327      REAL(wp) ::  MPI_Wtime 
     1328      MPI_Wtime = -1. 
     1329   END FUNCTION MPI_Wtime 
     1330#endif 
     1331 
     1332   !!---------------------------------------------------------------------- 
     1333   !!   ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam, load_nml   routines 
    17821334   !!---------------------------------------------------------------------- 
    17831335 
     
    17901342      !!                increment the error number (nstop) by one. 
    17911343      !!---------------------------------------------------------------------- 
    1792       CHARACTER(len=*), INTENT(in), OPTIONAL ::  cd1, cd2, cd3, cd4, cd5 
    1793       CHARACTER(len=*), INTENT(in), OPTIONAL ::  cd6, cd7, cd8, cd9, cd10 
     1344      CHARACTER(len=*), INTENT(in   )           ::   cd1 
     1345      CHARACTER(len=*), INTENT(in   ), OPTIONAL ::        cd2, cd3, cd4, cd5 
     1346      CHARACTER(len=*), INTENT(in   ), OPTIONAL ::   cd6, cd7, cd8, cd9, cd10 
     1347      ! 
     1348      CHARACTER(LEN=8) ::   clfmt            ! writing format 
     1349      INTEGER          ::   inum 
    17941350      !!---------------------------------------------------------------------- 
    17951351      ! 
    17961352      nstop = nstop + 1 
    1797  
    1798       ! force to open ocean.output file 
    1799       IF( numout == 6 ) CALL ctl_opn( numout, 'ocean.output', 'APPEND', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
    1800         
    1801       WRITE(numout,cform_err) 
    1802       IF( PRESENT(cd1 ) )   WRITE(numout,*) TRIM(cd1) 
     1353      ! 
     1354      IF( cd1 == 'STOP' .AND. narea /= 1 ) THEN    ! Immediate stop: add an arror message in 'ocean.output' file 
     1355         CALL ctl_opn( inum, 'ocean.output', 'APPEND', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
     1356         WRITE(inum,*) 
     1357         WRITE(inum,*) ' ==>>>   Look for "E R R O R" messages in all existing *ocean.output* files' 
     1358         CLOSE(inum) 
     1359      ENDIF 
     1360      IF( numout == 6 ) THEN                       ! force to open ocean.output file if not already opened 
     1361         CALL ctl_opn( numout, 'ocean.output', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, -1, .FALSE., narea ) 
     1362      ENDIF 
     1363      ! 
     1364                            WRITE(numout,*) 
     1365                            WRITE(numout,*) ' ===>>> : E R R O R' 
     1366                            WRITE(numout,*) 
     1367                            WRITE(numout,*) '         ===========' 
     1368                            WRITE(numout,*) 
     1369                            WRITE(numout,*) TRIM(cd1) 
    18031370      IF( PRESENT(cd2 ) )   WRITE(numout,*) TRIM(cd2) 
    18041371      IF( PRESENT(cd3 ) )   WRITE(numout,*) TRIM(cd3) 
     
    18101377      IF( PRESENT(cd9 ) )   WRITE(numout,*) TRIM(cd9) 
    18111378      IF( PRESENT(cd10) )   WRITE(numout,*) TRIM(cd10) 
    1812  
     1379                            WRITE(numout,*) 
     1380      ! 
    18131381                               CALL FLUSH(numout    ) 
    18141382      IF( numstp     /= -1 )   CALL FLUSH(numstp    ) 
    18151383      IF( numrun     /= -1 )   CALL FLUSH(numrun    ) 
     1384      IF( numevo_ice /= -1 )   CALL FLUSH(numevo_ice) 
    18161385      ! 
    18171386      IF( cd1 == 'STOP' ) THEN 
     1387         WRITE(numout,*)   
    18181388         WRITE(numout,*)  'huge E-R-R-O-R : immediate stop' 
    1819          CALL mppstop(ld_force_abort = .true.) 
     1389         WRITE(numout,*)   
     1390         CALL FLUSH(numout) 
     1391         CALL SLEEP(60)   ! make sure that all output and abort files are written by all cores. 60s should be enough... 
     1392         CALL mppstop( ld_abort = .true. ) 
    18201393      ENDIF 
    18211394      ! 
     
    18361409      ! 
    18371410      nwarn = nwarn + 1 
     1411      ! 
    18381412      IF(lwp) THEN 
    1839          WRITE(numout,cform_war) 
    1840          IF( PRESENT(cd1 ) ) WRITE(numout,*) TRIM(cd1) 
    1841          IF( PRESENT(cd2 ) ) WRITE(numout,*) TRIM(cd2) 
    1842          IF( PRESENT(cd3 ) ) WRITE(numout,*) TRIM(cd3) 
    1843          IF( PRESENT(cd4 ) ) WRITE(numout,*) TRIM(cd4) 
    1844          IF( PRESENT(cd5 ) ) WRITE(numout,*) TRIM(cd5) 
    1845          IF( PRESENT(cd6 ) ) WRITE(numout,*) TRIM(cd6) 
    1846          IF( PRESENT(cd7 ) ) WRITE(numout,*) TRIM(cd7) 
    1847          IF( PRESENT(cd8 ) ) WRITE(numout,*) TRIM(cd8) 
    1848          IF( PRESENT(cd9 ) ) WRITE(numout,*) TRIM(cd9) 
    1849          IF( PRESENT(cd10) ) WRITE(numout,*) TRIM(cd10) 
     1413                               WRITE(numout,*) 
     1414                               WRITE(numout,*) ' ===>>> : W A R N I N G' 
     1415                               WRITE(numout,*) 
     1416                               WRITE(numout,*) '         ===============' 
     1417                               WRITE(numout,*) 
     1418         IF( PRESENT(cd1 ) )   WRITE(numout,*) TRIM(cd1) 
     1419         IF( PRESENT(cd2 ) )   WRITE(numout,*) TRIM(cd2) 
     1420         IF( PRESENT(cd3 ) )   WRITE(numout,*) TRIM(cd3) 
     1421         IF( PRESENT(cd4 ) )   WRITE(numout,*) TRIM(cd4) 
     1422         IF( PRESENT(cd5 ) )   WRITE(numout,*) TRIM(cd5) 
     1423         IF( PRESENT(cd6 ) )   WRITE(numout,*) TRIM(cd6) 
     1424         IF( PRESENT(cd7 ) )   WRITE(numout,*) TRIM(cd7) 
     1425         IF( PRESENT(cd8 ) )   WRITE(numout,*) TRIM(cd8) 
     1426         IF( PRESENT(cd9 ) )   WRITE(numout,*) TRIM(cd9) 
     1427         IF( PRESENT(cd10) )   WRITE(numout,*) TRIM(cd10) 
     1428                               WRITE(numout,*) 
    18501429      ENDIF 
    18511430      CALL FLUSH(numout) 
     
    18731452      ! 
    18741453      CHARACTER(len=80) ::   clfile 
     1454      CHARACTER(LEN=10) ::   clfmt            ! writing format 
    18751455      INTEGER           ::   iost 
     1456      INTEGER           ::   idg              ! number of digits 
    18761457      !!---------------------------------------------------------------------- 
    18771458      ! 
     
    18801461      clfile = TRIM(cdfile) 
    18811462      IF( PRESENT( karea ) ) THEN 
    1882          IF( karea > 1 )   WRITE(clfile, "(a,'_',i4.4)") TRIM(clfile), karea-1 
     1463         IF( karea > 1 ) THEN 
     1464            ! Warning: jpnij is maybe not already defined when calling ctl_opn -> use mppsize instead of jpnij 
     1465            idg = MAX( INT(LOG10(REAL(MAX(1,mppsize-1),wp))) + 1, 4 )      ! how many digits to we need to write? min=4, max=9 
     1466            WRITE(clfmt, "('(a,a,i', i1, '.', i1, ')')") idg, idg          ! '(a,a,ix.x)' 
     1467            WRITE(clfile, clfmt) TRIM(clfile), '_', karea-1 
     1468         ENDIF 
    18831469      ENDIF 
    18841470#if defined key_agrif 
     
    18901476      IF( TRIM(cdfile) == '/dev/null' )   clfile = TRIM(cdfile)   ! force the use of /dev/null 
    18911477      ! 
    1892       iost=0 
    1893       IF( cdacce(1:6) == 'DIRECT' )  THEN         ! cdacce has always more than 6 characters 
     1478      IF(       cdacce(1:6) == 'DIRECT' )  THEN   ! cdacce has always more than 6 characters 
    18941479         OPEN( UNIT=knum, FILE=clfile, FORM=cdform, ACCESS=cdacce, STATUS=cdstat, RECL=klengh         , ERR=100, IOSTAT=iost ) 
    18951480      ELSE IF( TRIM(cdstat) == 'APPEND' )  THEN   ! cdstat can have less than 6 characters 
     
    19011486         &  OPEN(UNIT=knum,FILE='NUL', FORM=cdform, ACCESS=cdacce, STATUS=cdstat                      , ERR=100, IOSTAT=iost )    
    19021487      IF( iost == 0 ) THEN 
    1903          IF(ldwp) THEN 
     1488         IF(ldwp .AND. kout > 0) THEN 
    19041489            WRITE(kout,*) '     file   : ', TRIM(clfile),' open ok' 
    19051490            WRITE(kout,*) '     unit   = ', knum 
     
    19121497100   CONTINUE 
    19131498      IF( iost /= 0 ) THEN 
    1914          IF(ldwp) THEN 
    1915             WRITE(kout,*) 
    1916             WRITE(kout,*) ' ===>>>> : bad opening file: ', TRIM(clfile) 
    1917             WRITE(kout,*) ' =======   ===  ' 
    1918             WRITE(kout,*) '           unit   = ', knum 
    1919             WRITE(kout,*) '           status = ', cdstat 
    1920             WRITE(kout,*) '           form   = ', cdform 
    1921             WRITE(kout,*) '           access = ', cdacce 
    1922             WRITE(kout,*) '           iostat = ', iost 
    1923             WRITE(kout,*) '           we stop. verify the file ' 
    1924             WRITE(kout,*) 
    1925          ELSE  !!! Force writing to make sure we get the information - at least once - in this violent STOP!! 
    1926             WRITE(*,*) 
    1927             WRITE(*,*) ' ===>>>> : bad opening file: ', TRIM(clfile) 
    1928             WRITE(*,*) ' =======   ===  ' 
    1929             WRITE(*,*) '           unit   = ', knum 
    1930             WRITE(*,*) '           status = ', cdstat 
    1931             WRITE(*,*) '           form   = ', cdform 
    1932             WRITE(*,*) '           access = ', cdacce 
    1933             WRITE(*,*) '           iostat = ', iost 
    1934             WRITE(*,*) '           we stop. verify the file ' 
    1935             WRITE(*,*) 
    1936          ENDIF 
    1937          CALL FLUSH( kout )  
    1938          STOP 'ctl_opn bad opening' 
     1499         WRITE(ctmp1,*) ' ===>>>> : bad opening file: ', TRIM(clfile) 
     1500         WRITE(ctmp2,*) ' =======   ===  ' 
     1501         WRITE(ctmp3,*) '           unit   = ', knum 
     1502         WRITE(ctmp4,*) '           status = ', cdstat 
     1503         WRITE(ctmp5,*) '           form   = ', cdform 
     1504         WRITE(ctmp6,*) '           access = ', cdacce 
     1505         WRITE(ctmp7,*) '           iostat = ', iost 
     1506         WRITE(ctmp8,*) '           we stop. verify the file ' 
     1507         CALL ctl_stop( 'STOP', ctmp1, ctmp2, ctmp3, ctmp4, ctmp5, ctmp6, ctmp7, ctmp8 ) 
    19391508      ENDIF 
    19401509      ! 
     
    19421511 
    19431512 
    1944    SUBROUTINE ctl_nam ( kios, cdnam, ldwp ) 
     1513   SUBROUTINE ctl_nam ( kios, cdnam ) 
    19451514      !!---------------------------------------------------------------------- 
    19461515      !!                  ***  ROUTINE ctl_nam  *** 
     
    19501519      !! ** Method  :   Fortan open 
    19511520      !!---------------------------------------------------------------------- 
    1952       INTEGER         , INTENT(inout) ::   kios    ! IO status after reading the namelist 
    1953       CHARACTER(len=*), INTENT(in   ) ::   cdnam   ! group name of namelist for which error occurs 
    1954       CHARACTER(len=5)                ::   clios   ! string to convert iostat in character for print 
    1955       LOGICAL         , INTENT(in   ) ::   ldwp    ! boolean term for print 
     1521      INTEGER                                , INTENT(inout) ::   kios    ! IO status after reading the namelist 
     1522      CHARACTER(len=*)                       , INTENT(in   ) ::   cdnam   ! group name of namelist for which error occurs 
     1523      ! 
     1524      CHARACTER(len=5) ::   clios   ! string to convert iostat in character for print 
    19561525      !!---------------------------------------------------------------------- 
    19571526      ! 
     
    19671536      ENDIF 
    19681537      kios = 0 
    1969       RETURN 
    19701538      ! 
    19711539   END SUBROUTINE ctl_nam 
     
    19881556      END DO 
    19891557      IF( (get_unit == 999) .AND. llopn ) THEN 
    1990          CALL ctl_stop( 'get_unit: All logical units until 999 are used...' ) 
    1991          get_unit = -1 
     1558         CALL ctl_stop( 'STOP', 'get_unit: All logical units until 999 are used...' ) 
    19921559      ENDIF 
    19931560      ! 
    19941561   END FUNCTION get_unit 
    19951562 
     1563   SUBROUTINE load_nml( cdnambuff , cdnamfile, kout, ldwp) 
     1564      CHARACTER(LEN=:)    , ALLOCATABLE, INTENT(INOUT) :: cdnambuff 
     1565      CHARACTER(LEN=*), INTENT(IN )                :: cdnamfile 
     1566      CHARACTER(LEN=256)                           :: chline 
     1567      CHARACTER(LEN=1)                             :: csp 
     1568      INTEGER, INTENT(IN)                          :: kout 
     1569      LOGICAL, INTENT(IN)                          :: ldwp  !: .true. only for the root broadcaster 
     1570      INTEGER                                      :: itot, iun, iltc, inl, ios, itotsav 
     1571      ! 
     1572      !csp = NEW_LINE('A') 
     1573      ! a new line character is the best seperator but some systems (e.g.Cray) 
     1574      ! seem to terminate namelist reads from internal files early if they  
     1575      ! encounter new-lines. Use a single space for safety. 
     1576      csp = ' ' 
     1577      ! 
     1578      ! Check if the namelist buffer has already been allocated. Return if it has. 
     1579      ! 
     1580      IF ( ALLOCATED( cdnambuff ) ) RETURN 
     1581      IF( ldwp ) THEN 
     1582         ! 
     1583         ! Open namelist file 
     1584         ! 
     1585         CALL ctl_opn( iun, cdnamfile, 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, kout, ldwp ) 
     1586         ! 
     1587         ! First pass: count characters excluding comments and trimable white space 
     1588         ! 
     1589         itot=0 
     1590     10  READ(iun,'(A256)',END=20,ERR=20) chline 
     1591         iltc = LEN_TRIM(chline) 
     1592         IF ( iltc.GT.0 ) THEN 
     1593          inl = INDEX(chline, '!')  
     1594          IF( inl.eq.0 ) THEN 
     1595           itot = itot + iltc + 1                                ! +1 for the newline character 
     1596          ELSEIF( inl.GT.0 .AND. LEN_TRIM( chline(1:inl-1) ).GT.0 ) THEN 
     1597           itot = itot + inl                                  !  includes +1 for the newline character 
     1598          ENDIF 
     1599         ENDIF 
     1600         GOTO 10 
     1601     20  CONTINUE 
     1602         ! 
     1603         ! Allocate text cdnambuff for condensed namelist 
     1604         ! 
     1605!$AGRIF_DO_NOT_TREAT 
     1606         ALLOCATE( CHARACTER(LEN=itot) :: cdnambuff ) 
     1607!$AGRIF_END_DO_NOT_TREAT 
     1608         itotsav = itot 
     1609         ! 
     1610         ! Second pass: read and transfer pruned characters into cdnambuff 
     1611         ! 
     1612         REWIND(iun) 
     1613         itot=1 
     1614     30  READ(iun,'(A256)',END=40,ERR=40) chline 
     1615         iltc = LEN_TRIM(chline) 
     1616         IF ( iltc.GT.0 ) THEN 
     1617          inl = INDEX(chline, '!') 
     1618          IF( inl.eq.0 ) THEN 
     1619           inl = iltc 
     1620          ELSE 
     1621           inl = inl - 1 
     1622          ENDIF 
     1623          IF( inl.GT.0 .AND. LEN_TRIM( chline(1:inl) ).GT.0 ) THEN 
     1624             cdnambuff(itot:itot+inl-1) = chline(1:inl) 
     1625             WRITE( cdnambuff(itot+inl:itot+inl), '(a)' ) csp 
     1626             itot = itot + inl + 1 
     1627          ENDIF 
     1628         ENDIF 
     1629         GOTO 30 
     1630     40  CONTINUE 
     1631         itot = itot - 1 
     1632         IF( itotsav .NE. itot ) WRITE(*,*) 'WARNING in load_nml. Allocated ',itotsav,' for read buffer; but used ',itot 
     1633         ! 
     1634         ! Close namelist file 
     1635         ! 
     1636         CLOSE(iun) 
     1637         !write(*,'(32A)') cdnambuff 
     1638      ENDIF 
     1639#if defined key_mpp_mpi 
     1640      CALL mpp_bcast_nml( cdnambuff, itot ) 
     1641#endif 
     1642  END SUBROUTINE load_nml 
     1643 
     1644 
    19961645   !!---------------------------------------------------------------------- 
    19971646END MODULE lib_mpp 
  • utils/tools/DOMAINcfg/src/mpp_allreduce_generic.h90

    r13204 r14623  
    11!                          !==  IN: ptab is an array  ==! 
    22#   if defined REAL_TYPE 
    3 #      define ARRAY_TYPE(i)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i) 
    4 #      define TMP_TYPE(i)      REAL(wp)         , ALLOCATABLE   ::   work(i) 
    5 #      define MPI_TYPE mpi_double_precision 
     3#      if defined SINGLE_PRECISION 
     4#         define ARRAY_TYPE(i)    REAL(sp)         , INTENT(inout) ::   ARRAY_IN(i) 
     5#         define TMP_TYPE(i)      REAL(sp)         , ALLOCATABLE   ::   work(i) 
     6#         define MPI_TYPE mpi_real 
     7#      else 
     8#         define ARRAY_TYPE(i)    REAL(dp)         , INTENT(inout) ::   ARRAY_IN(i) 
     9#         define TMP_TYPE(i)      REAL(dp)         , ALLOCATABLE   ::   work(i) 
     10#         define MPI_TYPE mpi_double_precision 
     11#      endif  
    612#   endif 
    713#   if defined INTEGER_TYPE 
     
    1117#   endif 
    1218#   if defined COMPLEX_TYPE 
    13 #      define ARRAY_TYPE(i)    COMPLEX          , INTENT(inout) ::   ARRAY_IN(i) 
    14 #      define TMP_TYPE(i)      COMPLEX          , ALLOCATABLE   ::   work(i) 
     19#      define ARRAY_TYPE(i)    COMPLEX(dp)       , INTENT(inout) ::   ARRAY_IN(i) 
     20#      define TMP_TYPE(i)      COMPLEX(dp)       , ALLOCATABLE   ::   work(i) 
    1521#      define MPI_TYPE mpi_double_complex 
    1622#   endif 
     
    6167      ! 
    6268      ALLOCATE(work(ipi)) 
     69      IF( ln_timing ) CALL tic_tac(.TRUE., ld_global = .TRUE.) 
    6370      CALL mpi_allreduce( ARRAY_IN(:), work, ipi, MPI_TYPE, MPI_OPERATION, ilocalcomm, ierror ) 
     71      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
    6472      DO ii = 1, ipi 
    6573         ARRAY_IN(ii) = work(ii) 
     
    7381   END SUBROUTINE ROUTINE_ALLREDUCE 
    7482 
     83#undef PRECISION 
    7584#undef ARRAY_TYPE 
    7685#undef ARRAY_IN 
  • utils/tools/DOMAINcfg/src/mpp_lnk_generic.h90

    r13204 r14623  
    55#   define OPT_K(k)                 ,ipf 
    66#   if defined DIM_2d 
    7 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)                , INTENT(inout) ::   ptab(f) 
     7#      if defined SINGLE_PRECISION 
     8#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)                , INTENT(inout) ::   ptab(f) 
     9#      else 
     10#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)                , INTENT(inout) ::   ptab(f) 
     11#      endif 
    812#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
    913#      define K_SIZE(ptab)             1 
     
    1115#   endif 
    1216#   if defined DIM_3d 
    13 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)                , INTENT(inout) ::   ptab(f) 
     17#      if defined SINGLE_PRECISION 
     18#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)                , INTENT(inout) ::   ptab(f) 
     19#      else 
     20#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)                , INTENT(inout) ::   ptab(f) 
     21#      endif 
    1422#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
    1523#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
     
    1725#   endif 
    1826#   if defined DIM_4d 
    19 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)                , INTENT(inout) ::   ptab(f) 
     27#      if defined SINGLE_PRECISION 
     28#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)                , INTENT(inout) ::   ptab(f) 
     29#      else 
     30#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)                , INTENT(inout) ::   ptab(f) 
     31#      endif 
    2032#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
    2133#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
     
    2335#   endif 
    2436#else 
    25 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     37#   if defined SINGLE_PRECISION 
     38#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     39#   else 
     40#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     41#   endif 
    2642#   define NAT_IN(k)                cd_nat 
    2743#   define SGN_IN(k)                psgn 
     
    4561#endif 
    4662 
     63# if defined SINGLE_PRECISION 
     64#    define PRECISION sp 
     65#    define SENDROUTINE mppsend_sp 
     66#    define RECVROUTINE mpprecv_sp 
     67# else 
     68#    define PRECISION dp 
     69#    define SENDROUTINE mppsend_dp 
     70#    define RECVROUTINE mpprecv_dp 
     71# endif 
     72 
    4773#if defined MULTI 
    48    SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, cd_mpp, pval ) 
    49       INTEGER                     , INTENT(in   ) ::   kfld        ! number of pt3d arrays 
     74   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv ) 
     75      INTEGER             , INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    5076#else 
    51    SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , cd_mpp, pval ) 
     77   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval, lsend, lrecv ) 
    5278#endif 
    5379      ARRAY_TYPE(:,:,:,:,:)                                        ! array or pointer of arrays on which the boundary condition is applied 
    54       CHARACTER(len=*)            , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
    55       CHARACTER(len=1)            , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
    56       REAL(wp)                    , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
    57       CHARACTER(len=3), OPTIONAL  , INTENT(in   ) ::   cd_mpp      ! fill the overlap area only 
    58       REAL(wp)        , OPTIONAL  , INTENT(in   ) ::   pval        ! background value (used at closed boundaries) 
    59       ! 
    60       INTEGER  ::    ji,  jj,  jk,  jl, jh, jf   ! dummy loop indices 
     80      CHARACTER(len=*)              , INTENT(in   ) ::   cdname      ! name of the calling subroutine 
     81      CHARACTER(len=1)              , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
     82      REAL(wp)                      , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
     83      INTEGER ,             OPTIONAL, INTENT(in   ) ::   kfillmode   ! filling method for halo over land (default = constant) 
     84      REAL(wp),             OPTIONAL, INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries) 
     85      LOGICAL, DIMENSION(4),OPTIONAL, INTENT(in   ) ::   lsend, lrecv  ! communication with other 4 proc 
     86      ! 
     87      INTEGER  ::    ji,  jj,  jk,  jl,  jf      ! dummy loop indices 
    6188      INTEGER  ::   ipi, ipj, ipk, ipl, ipf      ! dimension of the input array 
    62       INTEGER  ::   imigr, iihom, ijhom          ! local integers 
    63       INTEGER  ::   ml_req1, ml_req2, ml_err     ! for key_mpi_isend 
     89      INTEGER  ::   isize, ishift, ishift2       ! local integers 
     90      INTEGER  ::   ireq_we, ireq_ea, ireq_so, ireq_no     ! mpi_request id 
    6491      INTEGER  ::   ierr 
     92      INTEGER  ::   ifill_we, ifill_ea, ifill_so, ifill_no 
    6593      REAL(wp) ::   zland 
    66       INTEGER , DIMENSION(MPI_STATUS_SIZE)      ::   ml_stat        ! for key_mpi_isend 
    67       REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ns, zt3sn   ! north-south & south-north  halos 
    68       REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ew, zt3we   ! east -west  & west - east  halos 
     94      INTEGER , DIMENSION(MPI_STATUS_SIZE)        ::   istat          ! for mpi_isend 
     95      REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos 
     96      REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos 
     97      LOGICAL  ::   llsend_we, llsend_ea, llsend_no, llsend_so       ! communication send 
     98      LOGICAL  ::   llrecv_we, llrecv_ea, llrecv_no, llrecv_so       ! communication receive  
     99      LOGICAL  ::   lldo_nfd                                     ! do north pole folding 
    69100      !!---------------------------------------------------------------------- 
     101      ! 
     102      ! ----------------------------------------- ! 
     103      !     0. local variables initialization     ! 
     104      ! ----------------------------------------- ! 
    70105      ! 
    71106      ipk = K_SIZE(ptab)   ! 3rd dimension 
     
    75110      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ipk, ipl, ipf, ld_lbc = .TRUE. ) 
    76111      ! 
    77       IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value 
    78       ELSE                         ;   zland = 0._wp     ! zero by default 
    79       ENDIF 
     112      IF     ( PRESENT(lsend) .AND. PRESENT(lrecv) ) THEN 
     113         llsend_we = lsend(1)   ;   llsend_ea = lsend(2)   ;   llsend_so = lsend(3)   ;   llsend_no = lsend(4) 
     114         llrecv_we = lrecv(1)   ;   llrecv_ea = lrecv(2)   ;   llrecv_so = lrecv(3)   ;   llrecv_no = lrecv(4) 
     115      ELSE IF( PRESENT(lsend) .OR.  PRESENT(lrecv) ) THEN 
     116         WRITE(ctmp1,*) ' E R R O R : Routine ', cdname, '  is calling lbc_lnk with only one of the two arguments lsend or lrecv' 
     117         WRITE(ctmp2,*) ' ========== ' 
     118         CALL ctl_stop( ' ', ctmp1, ctmp2, ' ' ) 
     119      ELSE   ! send and receive with every neighbour 
     120         llsend_we = nbondi ==  1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini 
     121         llsend_ea = nbondi == -1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini 
     122         llsend_so = nbondj ==  1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini 
     123         llsend_no = nbondj == -1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini 
     124         llrecv_we = llsend_we   ;   llrecv_ea = llsend_ea   ;   llrecv_so = llsend_so   ;   llrecv_no = llsend_no 
     125      END IF 
     126          
     127          
     128      lldo_nfd = npolj /= 0                      ! keep for compatibility, should be defined in mppini 
    80129 
    81       ! ------------------------------- ! 
    82       !   standard boundary treatment   !    ! CAUTION: semi-column notation is often impossible 
    83       ! ------------------------------- ! 
    84       ! 
    85       IF( .NOT. PRESENT( cd_mpp ) ) THEN     !==  standard close or cyclic treatment  ==! 
    86          ! 
    87          DO jf = 1, ipf                      ! number of arrays to be treated 
    88             ! 
    89             !                                ! East-West boundaries 
    90             IF( l_Iperio ) THEN                    !* cyclic 
    91                ARRAY_IN( 1 ,:,:,:,jf) = ARRAY_IN(jpim1,:,:,:,jf) 
    92                ARRAY_IN(jpi,:,:,:,jf) = ARRAY_IN(  2  ,:,:,:,jf) 
    93             ELSE                                   !* closed 
    94                IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(     1       :nn_hls,:,:,:,jf) = zland    ! east except F-point 
    95                                                ARRAY_IN(nlci-nn_hls+1:jpi   ,:,:,:,jf) = zland    ! west 
    96             ENDIF 
    97             !                                ! North-South boundaries 
    98             IF( l_Jperio ) THEN                    !* cyclic (only with no mpp j-split) 
    99                ARRAY_IN(:, 1 ,:,:,jf) = ARRAY_IN(:, jpjm1,:,:,jf) 
    100                ARRAY_IN(:,jpj,:,:,jf) = ARRAY_IN(:,   2  ,:,:,jf) 
    101             ELSE                                   !* closed 
    102                IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(:,     1       :nn_hls,:,:,jf) = zland    ! south except F-point 
    103                                                ARRAY_IN(:,nlcj-nn_hls+1:jpj   ,:,:,jf) = zland    ! north 
    104             ENDIF 
    105          END DO 
    106          ! 
    107       ENDIF 
     130      zland = 0._wp                                     ! land filling value: zero by default 
     131      IF( PRESENT( pfillval ) )   zland = pfillval      ! set land value 
    108132 
    109       ! ------------------------------- ! 
    110       !      East and west exchange     ! 
    111       ! ------------------------------- ! 
    112       ! we play with the neigbours AND the row number because of the periodicity 
    113       ! 
    114       IF( ABS(nbondi) == 1 ) ALLOCATE( zt3ew(jpj,nn_hls,ipk,ipl,ipf,1), zt3we(jpj,nn_hls,ipk,ipl,ipf,1) ) 
    115       IF(     nbondi  == 0 ) ALLOCATE( zt3ew(jpj,nn_hls,ipk,ipl,ipf,2), zt3we(jpj,nn_hls,ipk,ipl,ipf,2) ) 
    116       ! 
    117       SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions 
    118       CASE ( -1 ) 
    119          iihom = nlci-nreci 
    120          DO jf = 1, ipf 
    121             DO jl = 1, ipl 
    122                DO jk = 1, ipk 
    123                   DO jh = 1, nn_hls 
    124                      zt3we(:,jh,jk,jl,jf,1) = ARRAY_IN(iihom +jh,:,jk,jl,jf) 
    125                   END DO 
    126                END DO 
    127             END DO 
    128          END DO 
    129       CASE ( 0 ) 
    130          iihom = nlci-nreci 
    131          DO jf = 1, ipf 
    132             DO jl = 1, ipl 
    133                DO jk = 1, ipk 
    134                   DO jh = 1, nn_hls 
    135                      zt3ew(:,jh,jk,jl,jf,1) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf) 
    136                      zt3we(:,jh,jk,jl,jf,1) = ARRAY_IN(iihom +jh,:,jk,jl,jf) 
    137                   END DO 
    138                END DO 
    139             END DO 
    140          END DO 
    141       CASE ( 1 ) 
    142          iihom = nlci-nreci 
    143          DO jf = 1, ipf 
    144             DO jl = 1, ipl 
    145                DO jk = 1, ipk 
    146                   DO jh = 1, nn_hls 
    147                      zt3ew(:,jh,jk,jl,jf,1) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf) 
    148                   END DO 
    149                END DO 
    150             END DO 
    151          END DO 
     133      ! define the method we will use to fill the halos in each direction 
     134      IF(              llrecv_we ) THEN   ;   ifill_we = jpfillmpi 
     135      ELSEIF(           l_Iperio ) THEN   ;   ifill_we = jpfillperio 
     136      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_we = kfillmode 
     137      ELSE                                ;   ifill_we = jpfillcst 
     138      END IF 
     139      ! 
     140      IF(              llrecv_ea ) THEN   ;   ifill_ea = jpfillmpi 
     141      ELSEIF(           l_Iperio ) THEN   ;   ifill_ea = jpfillperio 
     142      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_ea = kfillmode 
     143      ELSE                                ;   ifill_ea = jpfillcst 
     144      END IF 
     145      ! 
     146      IF(              llrecv_so ) THEN   ;   ifill_so = jpfillmpi 
     147      ELSEIF(           l_Jperio ) THEN   ;   ifill_so = jpfillperio 
     148      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_so = kfillmode 
     149      ELSE                                ;   ifill_so = jpfillcst 
     150      END IF 
     151      ! 
     152      IF(              llrecv_no ) THEN   ;   ifill_no = jpfillmpi 
     153      ELSEIF(           l_Jperio ) THEN   ;   ifill_no = jpfillperio 
     154      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_no = kfillmode 
     155      ELSE                                ;   ifill_no = jpfillcst 
     156      END IF 
     157      ! 
     158#if defined PRINT_CAUTION 
     159      ! 
     160      ! ================================================================================== ! 
     161      ! CAUTION: semi-column notation is often impossible because of the cpp preprocessing ! 
     162      ! ================================================================================== ! 
     163      ! 
     164#endif 
     165      ! 
     166      ! -------------------------------------------------- ! 
     167      !     1. Do east and west MPI exchange if needed     ! 
     168      ! -------------------------------------------------- ! 
     169      ! 
     170      ! Must exchange the whole column (from 1 to jpj) to get the corners if we have no south/north neighbourg 
     171      isize = nn_hls * jpj * ipk * ipl * ipf       
     172      ! 
     173      ! Allocate local temporary arrays to be sent/received. Fill arrays to be sent 
     174      IF( llsend_we )   ALLOCATE( zsnd_we(nn_hls,jpj,ipk,ipl,ipf) ) 
     175      IF( llsend_ea )   ALLOCATE( zsnd_ea(nn_hls,jpj,ipk,ipl,ipf) ) 
     176      IF( llrecv_we )   ALLOCATE( zrcv_we(nn_hls,jpj,ipk,ipl,ipf) ) 
     177      IF( llrecv_ea )   ALLOCATE( zrcv_ea(nn_hls,jpj,ipk,ipl,ipf) ) 
     178      ! 
     179      IF( llsend_we ) THEN   ! copy western side of the inner mpi domain in local temporary array to be sent by MPI 
     180         ishift = nn_hls 
     181         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     182            zsnd_we(ji,jj,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! nn_hls + 1 -> 2*nn_hls 
     183         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     184      ENDIF 
     185      ! 
     186      IF(llsend_ea  ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI 
     187         ishift = jpi - 2 * nn_hls 
     188         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     189            zsnd_ea(ji,jj,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! jpi - 2*nn_hls + 1 -> jpi - nn_hls 
     190         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     191      ENDIF 
     192      ! 
     193      IF( ln_timing ) CALL tic_tac(.TRUE.) 
     194      ! 
     195      ! non-blocking send of the western/eastern side using local temporary arrays 
     196      IF( llsend_we )   CALL SENDROUTINE( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we ) 
     197      IF( llsend_ea )   CALL SENDROUTINE( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea ) 
     198      ! blocking receive of the western/eastern halo in local temporary arrays 
     199      IF( llrecv_we )   CALL RECVROUTINE( 2, zrcv_we(1,1,1,1,1), isize, nowe ) 
     200      IF( llrecv_ea )   CALL RECVROUTINE( 1, zrcv_ea(1,1,1,1,1), isize, noea ) 
     201      ! 
     202      IF( ln_timing ) CALL tic_tac(.FALSE.) 
     203      ! 
     204      ! 
     205      ! ----------------------------------- ! 
     206      !     2. Fill east and west halos     ! 
     207      ! ----------------------------------- ! 
     208      ! 
     209      ! 2.1 fill weastern halo 
     210      ! ---------------------- 
     211      ! ishift = 0                         ! fill halo from ji = 1 to nn_hls 
     212      SELECT CASE ( ifill_we ) 
     213      CASE ( jpfillnothing )               ! no filling  
     214      CASE ( jpfillmpi   )                 ! use data received by MPI  
     215         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     216            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_we(ji,jj,jk,jl,jf)   ! 1 -> nn_hls 
     217         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     218      CASE ( jpfillperio )                 ! use east-weast periodicity 
     219         ishift2 = jpi - 2 * nn_hls 
     220         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     221            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf) 
     222         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     223      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     224         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     225            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf) 
     226         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     227      CASE ( jpfillcst   )                 ! filling with constant value 
     228         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     229            ARRAY_IN(ji,jj,jk,jl,jf) = zland 
     230         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    152231      END SELECT 
    153       !                           ! Migrations 
    154       imigr = nn_hls * jpj * ipk * ipl * ipf       
    155       ! 
    156       SELECT CASE ( nbondi ) 
    157       CASE ( -1 ) 
    158          CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req1 ) 
    159          CALL mpprecv( 1, zt3ew(1,1,1,1,1,1), imigr, noea ) 
    160          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err) 
    161       CASE ( 0 ) 
    162          CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 ) 
    163          CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req2 ) 
    164          CALL mpprecv( 1, zt3ew(1,1,1,1,1,2), imigr, noea ) 
    165          CALL mpprecv( 2, zt3we(1,1,1,1,1,2), imigr, nowe ) 
    166          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err) 
    167          IF(l_isend)   CALL mpi_wait(ml_req2, ml_stat, ml_err) 
    168       CASE ( 1 ) 
    169          CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 ) 
    170          CALL mpprecv( 2, zt3we(1,1,1,1,1,1), imigr, nowe ) 
    171          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
     232      ! 
     233      ! 2.2 fill eastern halo 
     234      ! --------------------- 
     235      ishift = jpi - nn_hls                ! fill halo from ji = jpi-nn_hls+1 to jpi  
     236      SELECT CASE ( ifill_ea ) 
     237      CASE ( jpfillnothing )               ! no filling  
     238      CASE ( jpfillmpi   )                 ! use data received by MPI  
     239         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     240            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv_ea(ji,jj,jk,jl,jf)   ! jpi - nn_hls + 1 -> jpi 
     241         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     242      CASE ( jpfillperio )                 ! use east-weast periodicity 
     243         ishift2 = nn_hls 
     244         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     245            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf) 
     246         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     247      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     248         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     249            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf) 
     250         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     251      CASE ( jpfillcst   )                 ! filling with constant value 
     252         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls 
     253            ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland 
     254         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    172255      END SELECT 
    173       ! 
    174       !                           ! Write Dirichlet lateral conditions 
    175       iihom = nlci-nn_hls 
    176       ! 
    177       SELECT CASE ( nbondi ) 
    178       CASE ( -1 ) 
    179          DO jf = 1, ipf 
    180             DO jl = 1, ipl 
    181                DO jk = 1, ipk 
    182                   DO jh = 1, nn_hls 
    183                      ARRAY_IN(iihom+jh,:,jk,jl,jf) = zt3ew(:,jh,jk,jl,jf,1) 
    184                   END DO 
    185                END DO 
    186             END DO 
    187          END DO 
    188       CASE ( 0 ) 
    189          DO jf = 1, ipf 
    190             DO jl = 1, ipl 
    191                DO jk = 1, ipk 
    192                   DO jh = 1, nn_hls 
    193                      ARRAY_IN(jh      ,:,jk,jl,jf) = zt3we(:,jh,jk,jl,jf,2) 
    194                      ARRAY_IN(iihom+jh,:,jk,jl,jf) = zt3ew(:,jh,jk,jl,jf,2) 
    195                   END DO 
    196                END DO 
    197             END DO 
    198          END DO 
    199       CASE ( 1 ) 
    200          DO jf = 1, ipf 
    201             DO jl = 1, ipl 
    202                DO jk = 1, ipk 
    203                   DO jh = 1, nn_hls 
    204                      ARRAY_IN(jh      ,:,jk,jl,jf) = zt3we(:,jh,jk,jl,jf,1) 
    205                   END DO 
    206                END DO 
    207             END DO 
    208          END DO 
    209       END SELECT 
    210       ! 
    211       IF( nbondi /= 2 ) DEALLOCATE( zt3ew, zt3we ) 
    212256      ! 
    213257      ! ------------------------------- ! 
    214258      !     3. north fold treatment     ! 
    215259      ! ------------------------------- ! 
     260      ! 
    216261      ! do it before south directions so concerned processes can do it without waiting for the comm with the sourthern neighbor 
    217       IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN 
     262      ! 
     263      IF( lldo_nfd .AND. ifill_no /= jpfillnothing ) THEN 
    218264         ! 
    219265         SELECT CASE ( jpni ) 
    220          CASE ( 1 )     ;   CALL lbc_nfd( ptab, NAT_IN(:), SGN_IN(:) OPT_K(:) )   ! only 1 northern proc, no mpp 
    221          CASE DEFAULT   ;   CALL mpp_nfd( ptab, NAT_IN(:), SGN_IN(:) OPT_K(:) )   ! for all northern procs. 
     266         CASE ( 1 )     ;   CALL lbc_nfd( ptab, NAT_IN(:), SGN_IN(:)                  OPT_K(:) )   ! only 1 northern proc, no mpp 
     267         CASE DEFAULT   ;   CALL mpp_nfd( ptab, NAT_IN(:), SGN_IN(:), ifill_no, zland OPT_K(:) )   ! for all northern procs. 
    222268         END SELECT 
    223269         ! 
    224       ENDIF 
    225       ! 
    226       ! ------------------------------- ! 
    227       !  4. North and south directions  ! 
    228       ! ------------------------------- ! 
    229       ! always closed : we play only with the neigbours 
    230       ! 
    231       IF( ABS(nbondj) == 1 ) ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,1), zt3sn(jpi,nn_hls,ipk,ipl,ipf,1) ) 
    232       IF(     nbondj  == 0 ) ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,2), zt3sn(jpi,nn_hls,ipk,ipl,ipf,2) ) 
    233       ! 
    234       SELECT CASE ( nbondj ) 
    235       CASE ( -1 ) 
    236          ijhom = nlcj-nrecj 
    237          DO jf = 1, ipf 
    238             DO jl = 1, ipl 
    239                DO jk = 1, ipk 
    240                   DO jh = 1, nn_hls 
    241                      zt3sn(:,jh,jk,jl,jf,1) = ARRAY_IN(:,ijhom +jh,jk,jl,jf) 
    242                   END DO 
    243                END DO 
    244             END DO 
    245          END DO 
    246       CASE ( 0 ) 
    247          ijhom = nlcj-nrecj 
    248          DO jf = 1, ipf 
    249             DO jl = 1, ipl 
    250                DO jk = 1, ipk 
    251                   DO jh = 1, nn_hls 
    252                      zt3sn(:,jh,jk,jl,jf,1) = ARRAY_IN(:,ijhom +jh,jk,jl,jf) 
    253                      zt3ns(:,jh,jk,jl,jf,1) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf) 
    254                   END DO 
    255                END DO 
    256             END DO 
    257          END DO 
    258       CASE ( 1 ) 
    259          ijhom = nlcj-nrecj 
    260          DO jf = 1, ipf 
    261             DO jl = 1, ipl 
    262                DO jk = 1, ipk 
    263                   DO jh = 1, nn_hls 
    264                      zt3ns(:,jh,jk,jl,jf,1) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf) 
    265                   END DO 
    266                END DO 
    267             END DO 
    268          END DO 
     270         ifill_no = jpfillnothing  ! force to do nothing for the northern halo as we just done the north pole folding 
     271         ! 
     272      ENDIF 
     273      ! 
     274      ! ---------------------------------------------------- ! 
     275      !     4. Do north and south MPI exchange if needed     ! 
     276      ! ---------------------------------------------------- ! 
     277      ! 
     278      IF( llsend_so )   ALLOCATE( zsnd_so(jpi,nn_hls,ipk,ipl,ipf) ) 
     279      IF( llsend_no )   ALLOCATE( zsnd_no(jpi,nn_hls,ipk,ipl,ipf) ) 
     280      IF( llrecv_so )   ALLOCATE( zrcv_so(jpi,nn_hls,ipk,ipl,ipf) ) 
     281      IF( llrecv_no )   ALLOCATE( zrcv_no(jpi,nn_hls,ipk,ipl,ipf) ) 
     282      ! 
     283      isize = jpi * nn_hls * ipk * ipl * ipf       
     284 
     285      ! allocate local temporary arrays to be sent/received. Fill arrays to be sent 
     286      IF( llsend_so ) THEN   ! copy sourhern side of the inner mpi domain in local temporary array to be sent by MPI 
     287         ishift = nn_hls 
     288         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     289            zsnd_so(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! nn_hls+1 -> 2*nn_hls 
     290         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     291      ENDIF 
     292      ! 
     293      IF( llsend_no ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI 
     294         ishift = jpj - 2 * nn_hls 
     295         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     296            zsnd_no(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! jpj-2*nn_hls+1 -> jpj-nn_hls 
     297         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     298      ENDIF 
     299      ! 
     300      IF( ln_timing ) CALL tic_tac(.TRUE.) 
     301      ! 
     302      ! non-blocking send of the southern/northern side 
     303      IF( llsend_so )   CALL SENDROUTINE( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so ) 
     304      IF( llsend_no )   CALL SENDROUTINE( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no ) 
     305      ! blocking receive of the southern/northern halo 
     306      IF( llrecv_so )   CALL RECVROUTINE( 4, zrcv_so(1,1,1,1,1), isize, noso ) 
     307      IF( llrecv_no )   CALL RECVROUTINE( 3, zrcv_no(1,1,1,1,1), isize, nono ) 
     308      ! 
     309      IF( ln_timing ) CALL tic_tac(.FALSE.) 
     310      ! 
     311      ! ------------------------------------- ! 
     312      !     5. Fill south and north halos     ! 
     313      ! ------------------------------------- ! 
     314      ! 
     315      ! 5.1 fill southern halo 
     316      ! ---------------------- 
     317      ! ishift = 0                         ! fill halo from jj = 1 to nn_hls 
     318      SELECT CASE ( ifill_so ) 
     319      CASE ( jpfillnothing )               ! no filling  
     320      CASE ( jpfillmpi   )                 ! use data received by MPI  
     321         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     322            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_so(ji,jj,jk,jl,jf)   ! 1 -> nn_hls 
     323         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     324      CASE ( jpfillperio )                 ! use north-south periodicity 
     325         ishift2 = jpj - 2 * nn_hls 
     326         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     327            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf) 
     328         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     329      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     330         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     331            ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,nn_hls+1,jk,jl,jf) 
     332         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     333      CASE ( jpfillcst   )                 ! filling with constant value 
     334         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi  
     335            ARRAY_IN(ji,jj,jk,jl,jf) = zland 
     336         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    269337      END SELECT 
    270338      ! 
    271       !                           ! Migrations 
    272       imigr = nn_hls * jpi * ipk * ipl * ipf 
    273       ! 
    274       SELECT CASE ( nbondj ) 
    275       CASE ( -1 ) 
    276          CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req1 ) 
    277          CALL mpprecv( 3, zt3ns(1,1,1,1,1,1), imigr, nono ) 
    278          IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
    279       CASE ( 0 ) 
    280          CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 ) 
    281          CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req2 ) 
    282          CALL mpprecv( 3, zt3ns(1,1,1,1,1,2), imigr, nono ) 
    283          CALL mpprecv( 4, zt3sn(1,1,1,1,1,2), imigr, noso ) 
    284          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
    285          IF(l_isend)   CALL mpi_wait(ml_req2, ml_stat, ml_err ) 
    286       CASE ( 1 ) 
    287          CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 ) 
    288          CALL mpprecv( 4, zt3sn(1,1,1,1,1,1), imigr, noso ) 
    289          IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err ) 
     339      ! 5.2 fill northern halo 
     340      ! ---------------------- 
     341      ishift = jpj - nn_hls                ! fill halo from jj = jpj-nn_hls+1 to jpj  
     342      SELECT CASE ( ifill_no ) 
     343      CASE ( jpfillnothing )               ! no filling  
     344      CASE ( jpfillmpi   )                 ! use data received by MPI  
     345         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     346            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv_no(ji,jj,jk,jl,jf)   ! jpj-nn_hls+1 -> jpj 
     347         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     348      CASE ( jpfillperio )                 ! use north-south periodicity 
     349         ishift2 = nn_hls 
     350         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     351            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf) 
     352         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     353      CASE ( jpfillcopy  )                 ! filling with inner domain values 
     354         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     355            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift,jk,jl,jf) 
     356         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
     357      CASE ( jpfillcst   )                 ! filling with constant value 
     358         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi 
     359            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zland 
     360         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO 
    290361      END SELECT 
    291362      ! 
    292       ijhom = nlcj-nn_hls 
    293       ! 
    294       SELECT CASE ( nbondj ) 
    295       CASE ( -1 ) 
    296          DO jf = 1, ipf 
    297             DO jl = 1, ipl 
    298                DO jk = 1, ipk 
    299                   DO jh = 1, nn_hls 
    300                      ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zt3ns(:,jh,jk,jl,jf,1) 
    301                   END DO 
    302                END DO 
    303             END DO 
    304          END DO 
    305       CASE ( 0 ) 
    306          DO jf = 1, ipf 
    307             DO jl = 1, ipl 
    308                DO jk = 1, ipk 
    309                   DO jh = 1, nn_hls 
    310                      ARRAY_IN(:,      jh,jk,jl,jf) = zt3sn(:,jh,jk,jl,jf,2) 
    311                      ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zt3ns(:,jh,jk,jl,jf,2) 
    312                   END DO 
    313                END DO 
    314             END DO 
    315          END DO 
    316       CASE ( 1 ) 
    317          DO jf = 1, ipf 
    318             DO jl = 1, ipl 
    319                DO jk = 1, ipk 
    320                   DO jh = 1, nn_hls 
    321                      ARRAY_IN(:,jh,jk,jl,jf) = zt3sn(:,jh,jk,jl,jf,1) 
    322                   END DO 
    323                END DO 
    324             END DO 
    325          END DO 
    326       END SELECT 
    327       ! 
    328       IF( nbondj /= 2 ) DEALLOCATE( zt3ns, zt3sn ) 
     363      ! -------------------------------------------- ! 
     364      !     6. deallocate local temporary arrays     ! 
     365      ! -------------------------------------------- ! 
     366      ! 
     367      IF( llsend_we ) THEN 
     368         CALL mpi_wait(ireq_we, istat, ierr ) 
     369         DEALLOCATE( zsnd_we ) 
     370      ENDIF 
     371      IF( llsend_ea )  THEN 
     372         CALL mpi_wait(ireq_ea, istat, ierr ) 
     373         DEALLOCATE( zsnd_ea ) 
     374      ENDIF 
     375      IF( llsend_so ) THEN 
     376         CALL mpi_wait(ireq_so, istat, ierr ) 
     377         DEALLOCATE( zsnd_so ) 
     378      ENDIF 
     379      IF( llsend_no ) THEN 
     380         CALL mpi_wait(ireq_no, istat, ierr ) 
     381         DEALLOCATE( zsnd_no ) 
     382      ENDIF 
     383      ! 
     384      IF( llrecv_we )   DEALLOCATE( zrcv_we ) 
     385      IF( llrecv_ea )   DEALLOCATE( zrcv_ea ) 
     386      IF( llrecv_so )   DEALLOCATE( zrcv_so ) 
     387      IF( llrecv_no )   DEALLOCATE( zrcv_no ) 
    329388      ! 
    330389   END SUBROUTINE ROUTINE_LNK 
    331  
     390#undef PRECISION 
     391#undef SENDROUTINE 
     392#undef RECVROUTINE 
    332393#undef ARRAY_TYPE 
    333394#undef NAT_IN 
  • utils/tools/DOMAINcfg/src/mpp_loc_generic.h90

    r13204 r14623  
    11                          !==  IN: ptab is an array  ==! 
    2 #      define ARRAY_TYPE(i,j,k)    REAL(wp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k) 
    3 #      define MASK_TYPE(i,j,k)     REAL(wp)        , INTENT(in   ) ::   MASK_IN(i,j,k) 
     2#   if defined SINGLE_PRECISION 
     3#      define ARRAY_TYPE(i,j,k)    REAL(sp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k) 
     4#      define MASK_TYPE(i,j,k)     REAL(sp)        , INTENT(in   ) ::   MASK_IN(i,j,k) 
     5#      define PRECISION sp 
     6#   else 
     7#      define ARRAY_TYPE(i,j,k)    REAL(dp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k) 
     8#      define MASK_TYPE(i,j,k)     REAL(dp)        , INTENT(in   ) ::   MASK_IN(i,j,k) 
     9#      define PRECISION dp 
     10#   endif 
     11 
    412#   if defined DIM_2d 
    513#      define ARRAY_IN(i,j,k)   ptab(i,j) 
     
    1725#      define MPI_OPERATION mpi_maxloc 
    1826#      define LOC_OPERATION MAXLOC 
     27#      define ERRVAL -HUGE 
    1928#   endif 
    2029#   if defined OPERATION_MINLOC 
    2130#      define MPI_OPERATION mpi_minloc 
    2231#      define LOC_OPERATION MINLOC 
     32#      define ERRVAL HUGE 
    2333#   endif 
    2434 
     
    2838      ARRAY_TYPE(:,:,:)                            ! array on which loctrans operation is applied 
    2939      MASK_TYPE(:,:,:)                             ! local mask 
    30       REAL(wp)        , INTENT(  out) ::   pmin    ! Global minimum of ptab 
     40      REAL(PRECISION)        , INTENT(  out) ::   pmin    ! Global minimum of ptab 
    3141      INDEX_TYPE(:)                                ! index of minimum in global frame 
    32 # if defined key_mpp_mpi 
    3342      ! 
    3443      INTEGER  ::   ierror, ii, idim 
    3544      INTEGER  ::   index0 
    36       REAL(wp) ::   zmin     ! local minimum 
     45      REAL(PRECISION) ::   zmin     ! local minimum 
    3746      INTEGER , DIMENSION(:), ALLOCATABLE  ::   ilocs 
    38       REAL(wp), DIMENSION(2,1) ::   zain, zaout 
     47      REAL(dp), DIMENSION(2,1) ::   zain, zaout 
    3948      !!----------------------------------------------------------------------- 
    4049      ! 
     
    4251      ! 
    4352      idim = SIZE(kindex) 
    44       ALLOCATE ( ilocs(idim) ) 
    4553      ! 
    46       ilocs = LOC_OPERATION( ARRAY_IN(:,:,:) , mask= MASK_IN(:,:,:) == 1._wp ) 
    47       zmin  = ARRAY_IN(ilocs(1),ilocs(2),ilocs(3)) 
    48       ! 
    49       kindex(1) = ilocs(1) + nimpp - 1 
    50 #  if defined DIM_2d || defined DIM_3d    /* avoid warning when kindex has 1 element */ 
    51       kindex(2) = ilocs(2) + njmpp - 1 
    52 #  endif 
    53 #  if defined DIM_3d                      /* avoid warning when kindex has 2 elements */ 
    54       kindex(3) = ilocs(3) 
    55 #  endif 
    56       !  
    57       DEALLOCATE (ilocs) 
    58       ! 
    59       index0 = kindex(1)-1   ! 1d index starting at 0 
    60 #  if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
    61       index0 = index0 + jpiglo * (kindex(2)-1) 
    62 #  endif 
    63 #  if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
    64       index0 = index0 + jpiglo * jpjglo * (kindex(3)-1) 
    65 #  endif 
     54      IF ( ALL(MASK_IN(:,:,:) /= 1._wp) ) THEN 
     55         ! special case for land processors 
     56         zmin = ERRVAL(zmin) 
     57         index0 = 0 
     58      ELSE 
     59         ALLOCATE ( ilocs(idim) ) 
     60         ! 
     61         ilocs = LOC_OPERATION( ARRAY_IN(:,:,:) , mask= MASK_IN(:,:,:) == 1._wp ) 
     62         zmin  = ARRAY_IN(ilocs(1),ilocs(2),ilocs(3)) 
     63         ! 
     64         kindex(1) = mig( ilocs(1) ) 
     65#if defined DIM_2d || defined DIM_3d    /* avoid warning when kindex has 1 element */ 
     66         kindex(2) = mjg( ilocs(2) ) 
     67#endif 
     68#if defined DIM_3d                      /* avoid warning when kindex has 2 elements */ 
     69         kindex(3) = ilocs(3) 
     70#endif 
     71         !  
     72         DEALLOCATE (ilocs) 
     73         ! 
     74         index0 = kindex(1)-1   ! 1d index starting at 0 
     75#if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
     76         index0 = index0 + jpiglo * (kindex(2)-1) 
     77#endif 
     78#if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
     79         index0 = index0 + jpiglo * jpjglo * (kindex(3)-1) 
     80#endif 
     81      END IF 
    6682      zain(1,:) = zmin 
    6783      zain(2,:) = REAL(index0, wp) 
    6884      ! 
     85      IF( ln_timing ) CALL tic_tac(.TRUE., ld_global = .TRUE.) 
     86#if defined key_mpp_mpi 
    6987      CALL MPI_ALLREDUCE( zain, zaout, 1, MPI_2DOUBLE_PRECISION, MPI_OPERATION ,MPI_COMM_OCE, ierror) 
     88#else 
     89      zaout(:,:) = zain(:,:) 
     90#endif 
     91      IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 
    7092      ! 
    7193      pmin      = zaout(1,1) 
    7294      index0    = NINT( zaout(2,1) ) 
    73 #  if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
     95#if defined DIM_3d                     /* avoid warning when kindex has 2 elements */ 
    7496      kindex(3) = index0 / (jpiglo*jpjglo) 
    7597      index0    = index0 - kindex(3) * (jpiglo*jpjglo) 
    76 #  endif 
    77 #  if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
     98#endif 
     99#if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */ 
    78100      kindex(2) = index0 / jpiglo 
    79101      index0 = index0 - kindex(2) * jpiglo 
    80 #  endif 
     102#endif 
    81103      kindex(1) = index0 
    82104      kindex(:) = kindex(:) + 1   ! start indices at 1 
    83 #else 
    84       kindex = 0 ; pmin = 0. 
    85       WRITE(*,*) 'ROUTINE_LOC: You should not have seen this print! error?' 
    86 #endif 
    87105 
    88106   END SUBROUTINE ROUTINE_LOC 
    89107 
     108 
     109#undef PRECISION 
    90110#undef ARRAY_TYPE 
    91 #undef MAX_TYPE 
     111#undef MASK_TYPE 
    92112#undef ARRAY_IN 
    93113#undef MASK_IN 
     
    96116#undef LOC_OPERATION 
    97117#undef INDEX_TYPE 
     118#undef ERRVAL 
  • utils/tools/DOMAINcfg/src/mpp_nfd_generic.h90

    r13204 r14623  
    55#   define LBC_ARG                  (jf) 
    66#   if defined DIM_2d 
    7 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)     , INTENT(inout) ::   ptab(f) 
     7#      if defined SINGLE_PRECISION 
     8#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)     , INTENT(inout) ::   ptab(f) 
     9#      else 
     10#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)     , INTENT(inout) ::   ptab(f) 
     11#      endif 
    812#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j) 
    913#      define K_SIZE(ptab)             1 
     
    1115#   endif 
    1216#   if defined DIM_3d 
    13 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)     , INTENT(inout) ::   ptab(f) 
     17#      if defined SINGLE_PRECISION 
     18#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)     , INTENT(inout) ::   ptab(f) 
     19#      else 
     20#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)     , INTENT(inout) ::   ptab(f) 
     21#      endif 
    1422#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k) 
    1523#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3) 
     
    1725#   endif 
    1826#   if defined DIM_4d 
    19 #      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)     , INTENT(inout) ::   ptab(f) 
     27#      if defined SINGLE_PRECISION 
     28#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)     , INTENT(inout) ::   ptab(f) 
     29#      else 
     30#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)     , INTENT(inout) ::   ptab(f) 
     31#      endif 
    2032#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l) 
    2133#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3) 
     
    2436#else 
    2537!                          !==  IN: ptab is an array  ==! 
    26 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     38#   if defined SINGLE_PRECISION 
     39#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     40#   else 
     41#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f) 
     42#   endif 
    2743#   define NAT_IN(k)                cd_nat 
    2844#   define SGN_IN(k)                psgn 
     
    4662#endif 
    4763 
    48    SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kfld ) 
     64# if defined SINGLE_PRECISION 
     65#    define PRECISION sp 
     66#    define SENDROUTINE mppsend_sp 
     67#    define RECVROUTINE mpprecv_sp 
     68#    define MPI_TYPE MPI_REAL 
     69#    define HUGEVAL(x)   HUGE(x/**/_sp) 
     70# else 
     71#    define PRECISION dp 
     72#    define SENDROUTINE mppsend_dp 
     73#    define RECVROUTINE mpprecv_dp 
     74#    define MPI_TYPE MPI_DOUBLE_PRECISION 
     75#    define HUGEVAL(x)   HUGE(x/**/_dp) 
     76# endif 
     77 
     78   SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kfillmode, pfillval, kfld ) 
    4979      !!---------------------------------------------------------------------- 
    5080      ARRAY_TYPE(:,:,:,:,:)   ! array or pointer of arrays on which the boundary condition is applied 
    5181      CHARACTER(len=1) , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points 
    5282      REAL(wp)         , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary 
     83      INTEGER          , INTENT(in   ) ::   kfillmode   ! filling method for halo over land  
     84      REAL(wp)         , INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries) 
    5385      INTEGER, OPTIONAL, INTENT(in   ) ::   kfld        ! number of pt3d arrays 
    5486      ! 
     87      LOGICAL  ::   ll_add_line 
    5588      INTEGER  ::   ji,  jj,  jk,  jl, jh, jf, jr   ! dummy loop indices 
    56       INTEGER  ::   ipi, ipj, ipk, ipl, ipf         ! dimension of the input array 
     89      INTEGER  ::   ipi, ipj, ipj2, ipk, ipl, ipf   ! dimension of the input array 
    5790      INTEGER  ::   imigr, iihom, ijhom             ! local integers 
    58       INTEGER  ::   ierr, ibuffsize, ilci, ildi, ilei, iilb 
    59       INTEGER  ::   ij, iproc 
     91      INTEGER  ::   ierr, ibuffsize, iis0, iie0, impp 
     92      INTEGER  ::   ii1, ii2, ij1, ij2 
     93      INTEGER  ::   ipimax, i0max 
     94      INTEGER  ::   ij, iproc, ipni, ijnr 
    6095      INTEGER, DIMENSION (jpmaxngh)       ::   ml_req_nf   ! for mpi_isend when avoiding mpi_allgather 
    6196      INTEGER                             ::   ml_err      ! for mpi_isend when avoiding mpi_allgather 
    6297      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat     ! for mpi_isend when avoiding mpi_allgather 
    6398      !                                                    ! Workspace for message transfers avoiding mpi_allgather 
    64       INTEGER                             ::   ipf_j       ! sum of lines for all multi fields 
    65       INTEGER                             ::   js          ! counter 
    66       INTEGER, DIMENSION(:,:),          ALLOCATABLE ::   jj_s  ! position of sent lines 
    67       INTEGER, DIMENSION(:),            ALLOCATABLE ::   ipj_s ! number of sent lines 
    68       REAL(wp), DIMENSION(:,:,:)      , ALLOCATABLE ::   ztabl 
    69       REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztab, ztabr 
    70       REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   znorthloc, zfoldwk       
    71       REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthgloio 
     99      INTEGER                             ::   ipj_b       ! sum of lines for all multi fields 
     100      INTEGER                             ::   i012        ! 0, 1 or 2 
     101      INTEGER , DIMENSION(:,:)        , ALLOCATABLE ::   jj_s  ! position of sent lines 
     102      INTEGER , DIMENSION(:,:)        , ALLOCATABLE ::   jj_b  ! position of buffer lines 
     103      INTEGER , DIMENSION(:)          , ALLOCATABLE ::   ipj_s ! number of sent lines 
     104      REAL(PRECISION), DIMENSION(:,:,:,:)    , ALLOCATABLE ::   ztabb, ztabr, ztabw  ! buffer, receive and work arrays 
     105      REAL(PRECISION), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztabglo, znorthloc 
     106      REAL(PRECISION), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthglo 
    72107      !!---------------------------------------------------------------------- 
    73108      ! 
     
    76111      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers) 
    77112      ! 
    78       IF( l_north_nogather ) THEN      !==  ????  ==! 
     113      IF( l_north_nogather ) THEN      !==  no allgather exchanges  ==! 
    79114 
    80          ALLOCATE(ipj_s(ipf)) 
    81  
    82          ipj      = 2            ! Max 2nd dimension of message transfers (last two j-line only) 
    83          ipj_s(:) = 1            ! Real 2nd dimension of message transfers (depending on perf requirement) 
    84                                  ! by default, only one line is exchanged 
    85  
    86          ALLOCATE( jj_s(ipf,2) ) 
    87  
    88          ! re-define number of exchanged lines : 
    89          !  must be two during the first two time steps 
    90          !  to correct possible incoherent values on North fold lines from restart  
    91  
     115         !   ---   define number of exchanged lines   --- 
     116         ! 
     117         ! In theory we should exchange only nn_hls lines. 
     118         ! 
     119         ! However, some other points are duplicated in the north pole folding: 
     120         !  - jperio=[34], grid=T : half of the last line (jpiglo/2+2:jpiglo-nn_hls) 
     121         !  - jperio=[34], grid=U : half of the last line (jpiglo/2+1:jpiglo-nn_hls) 
     122         !  - jperio=[34], grid=V : all the last line nn_hls+1 and (nn_hls+2:jpiglo-nn_hls) 
     123         !  - jperio=[34], grid=F : all the last line (nn_hls+1:jpiglo-nn_hls) 
     124         !  - jperio=[56], grid=T : 2 points of the last line (jpiglo/2+1 and jpglo-nn_hls) 
     125         !  - jperio=[56], grid=U : no points are duplicated 
     126         !  - jperio=[56], grid=V : half of the last line (jpiglo/2+1:jpiglo-nn_hls) 
     127         !  - jperio=[56], grid=F : half of the last line (jpiglo/2+1:jpiglo-nn_hls-1) 
     128         ! The order of the calculations may differ for these duplicated points (as, for example jj+1 becomes jj-1) 
     129         ! This explain why these duplicated points may have different values even if they are at the exact same location. 
     130         ! In consequence, we may want to force the folding on these points by setting l_full_nf_update = .TRUE. 
     131         ! This is slightly slower but necessary to avoid different values on identical grid points!! 
     132         ! 
    92133         !!!!!!!!!           temporary switch off this optimisation ==> force TRUE           !!!!!!!! 
    93134         !!!!!!!!!  needed to get the same results without agrif and with agrif and no zoom  !!!!!!!! 
    94135         !!!!!!!!!                    I don't know why we must do that...                    !!!!!!!! 
    95136         l_full_nf_update = .TRUE. 
    96  
    97          ipj_s(:) = 2 
     137         ! also force it if not restart during the first 2 steps (leap frog?) 
     138         ll_add_line = l_full_nf_update .OR. ( ncom_stp <= nit000+1 .AND. .NOT. ln_rstart ) 
     139          
     140         ALLOCATE(ipj_s(ipf))                ! how many lines do we exchange? 
     141         IF( ll_add_line ) THEN 
     142            DO jf = 1, ipf                      ! Loop over the number of arrays to be processed 
     143               ipj_s(jf) = nn_hls + COUNT( (/ npolj == 3 .OR. npolj == 4 .OR. NAT_IN(jf) == 'V' .OR. NAT_IN(jf) == 'F' /) )  
     144            END DO 
     145         ELSE 
     146            ipj_s(:) = nn_hls 
     147         ENDIF 
     148          
     149         ipj   = MAXVAL(ipj_s(:))            ! Max 2nd dimension of message transfers 
     150         ipj_b = SUM(   ipj_s(:))            ! Total number of lines to be exchanged 
     151         ALLOCATE( jj_s(ipj, ipf), jj_b(ipj, ipf) ) 
    98152 
    99153         ! Index of modifying lines in input 
     154         ij1 = 0 
    100155         DO jf = 1, ipf                      ! Loop over the number of arrays to be processed 
    101156            ! 
    102157            SELECT CASE ( npolj ) 
    103             ! 
    104158            CASE ( 3, 4 )                       ! *  North fold  T-point pivot 
    105                ! 
    106159               SELECT CASE ( NAT_IN(jf) ) 
    107                ! 
    108                CASE ( 'T' , 'W' ,'U' )                            ! T-, U-, W-point 
    109                   jj_s(jf,1) = nlcj - 2 ;  jj_s(jf,2) = nlcj - 1 
    110                CASE ( 'V' , 'F' )                                 ! V-, F-point 
    111                   jj_s(jf,1) = nlcj - 3 ;  jj_s(jf,2) = nlcj - 2 
     160               CASE ( 'T', 'W', 'U' )   ;   i012 = 1   ! T-, U-, W-point 
     161               CASE ( 'V', 'F'      )   ;   i012 = 2   ! V-, F-point 
    112162               END SELECT 
    113             ! 
    114             CASE ( 5, 6 )                        ! *  North fold  F-point pivot 
     163            CASE ( 5, 6 )                       ! *  North fold  F-point pivot 
    115164               SELECT CASE ( NAT_IN(jf) ) 
    116                ! 
    117                CASE ( 'T' , 'W' ,'U' )                            ! T-, U-, W-point 
    118                   jj_s(jf,1) = nlcj - 1       
    119                   ipj_s(jf) = 1                  ! need only one line anyway 
    120                CASE ( 'V' , 'F' )                                 ! V-, F-point 
    121                   jj_s(jf,1) = nlcj - 2 ;  jj_s(jf,2) = nlcj - 1 
     165               CASE ( 'T', 'W', 'U' )   ;   i012 = 0   ! T-, U-, W-point 
     166               CASE ( 'V', 'F'      )   ;   i012 = 1   ! V-, F-point 
    122167               END SELECT 
    123             ! 
    124168            END SELECT 
    125             ! 
    126          ENDDO 
    127          !  
    128          ipf_j = sum (ipj_s(:))      ! Total number of lines to be exchanged 
    129          ! 
    130          ALLOCATE( znorthloc(jpimax,ipf_j,ipk,ipl,1) ) 
    131          ! 
    132          js = 0 
    133          DO jf = 1, ipf                      ! Loop over the number of arrays to be processed 
     169               ! 
    134170            DO jj = 1, ipj_s(jf) 
    135                js = js + 1 
    136                DO jl = 1, ipl 
    137                   DO jk = 1, ipk 
    138                      znorthloc(1:jpi,js,jk,jl,1) = ARRAY_IN(1:jpi,jj_s(jf,jj),jk,jl,jf) 
     171               ij1 = ij1 + 1 
     172               jj_b(jj,jf) = ij1 
     173               jj_s(jj,jf) = jpj - 2*nn_hls + jj - i012 
     174            END DO 
     175            ! 
     176         END DO 
     177         ! 
     178         ALLOCATE( ztabb(jpimax,ipj_b,ipk,ipl) )   ! store all the data to be sent in a buffer array 
     179         ibuffsize = jpimax * ipj_b * ipk * ipl 
     180         ! 
     181         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     182            DO jj = 1, ipj_s(jf) 
     183               ij1 = jj_b(jj,jf) 
     184               ij2 = jj_s(jj,jf) 
     185               DO ji = 1, jpi 
     186                  ztabb(ji,ij1,jk,jl) = ARRAY_IN(ji,ij2,jk,jl,jf) 
     187               END DO 
     188               DO ji = jpi+1, jpimax 
     189                  ztabb(ji,ij1,jk,jl) = HUGEVAL(0.)   ! avoid sending uninitialized values (make sure we don't use it) 
     190               END DO 
     191            END DO 
     192         END DO   ;   END DO   ;   END DO 
     193         ! 
     194         ! start waiting time measurement 
     195         IF( ln_timing ) CALL tic_tac(.TRUE.) 
     196         ! 
     197         ! send the data as soon as possible 
     198         DO jr = 1, nsndto 
     199            iproc = nfproc(isendto(jr)) 
     200            IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN 
     201               CALL SENDROUTINE( 5, ztabb, ibuffsize, iproc, ml_req_nf(jr) ) 
     202            ENDIF 
     203         END DO 
     204         ! 
     205         ipimax = jpimax * jpmaxngh 
     206         ALLOCATE( ztabw(jpimax,ipj_b,ipk,ipl), ztabr(ipimax,ipj_b,ipk,ipl) )  
     207         ! 
     208         DO jr = 1, nsndto 
     209            ! 
     210            ipni  = isendto(jr) 
     211            iproc = nfproc(ipni) 
     212            ipi   = nfjpi (ipni) 
     213            ! 
     214            IF( ipni ==   1  ) THEN   ;   iis0 =   1            ! domain  left side: as e-w comm already done -> from 1st column 
     215            ELSE                      ;   iis0 =   1 + nn_hls   ! default: -> from inner domain  
     216            ENDIF 
     217            IF( ipni == jpni ) THEN   ;   iie0 = ipi            ! domain right side: as e-w comm already done -> until last column 
     218            ELSE                      ;   iie0 = ipi - nn_hls   ! default: -> until inner domain  
     219            ENDIF 
     220            impp = nfimpp(ipni) - nfimpp(isendto(1)) 
     221            ! 
     222            IF(           iproc == -1 ) THEN   ! No neighbour (land proc that was suppressed) 
     223               ! 
     224               SELECT CASE ( kfillmode ) 
     225               CASE ( jpfillnothing )               ! no filling  
     226               CASE ( jpfillcopy    )               ! filling with inner domain values 
     227                  DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     228                     DO jj = 1, ipj_s(jf) 
     229                        ij1 = jj_b(jj,jf) 
     230                        ij2 = jj_s(jj,jf) 
     231                        DO ji = iis0, iie0 
     232                           ztabr(impp+ji,ij1,jk,jl) = ARRAY_IN(Nis0,ij2,jk,jl,jf)   ! chose to take the 1st iner domain point 
     233                        END DO 
     234                     END DO 
     235                  END DO   ;   END DO   ;   END DO 
     236               CASE ( jpfillcst     )               ! filling with constant value 
     237                  DO jl = 1, ipl   ;   DO jk = 1, ipk 
     238                     DO jj = 1, ipj_b 
     239                        DO ji = iis0, iie0 
     240                           ztabr(impp+ji,jj,jk,jl) = pfillval 
     241                        END DO 
     242                     END DO 
     243                  END DO   ;   END DO 
     244               END SELECT 
     245               ! 
     246            ELSE IF( iproc == narea-1 ) THEN   ! get data from myself! 
     247               ! 
     248               DO jf = 1, ipf   ;   DO jl = 1, ipl  ;   DO jk = 1, ipk 
     249                  DO jj = 1, ipj_s(jf) 
     250                     ij1 = jj_b(jj,jf) 
     251                     ij2 = jj_s(jj,jf) 
     252                     DO ji = iis0, iie0 
     253                        ztabr(impp+ji,ij1,jk,jl) = ARRAY_IN(ji,ij2,jk,jl,jf) 
     254                     END DO 
    139255                  END DO 
     256               END DO   ;   END DO   ;   END DO 
     257               ! 
     258            ELSE                               ! get data from a neighbour trough communication 
     259               !   
     260               CALL RECVROUTINE(5, ztabw, ibuffsize, iproc) 
     261               DO jl = 1, ipl   ;   DO jk = 1, ipk 
     262                  DO jj = 1, ipj_b 
     263                     DO ji = iis0, iie0 
     264                        ztabr(impp+ji,jj,jk,jl) = ztabw(ji,jj,jk,jl) 
     265                     END DO 
     266                  END DO 
     267               END DO   ;   END DO 
     268                
     269            ENDIF 
     270            ! 
     271         END DO   ! nsndto 
     272         ! 
     273         IF( ln_timing ) CALL tic_tac(.FALSE.) 
     274         ! 
     275         ! North fold boundary condition 
     276         ! 
     277         DO jf = 1, ipf 
     278            ij1 = jj_b(       1 ,jf) 
     279            ij2 = jj_b(ipj_s(jf),jf) 
     280            CALL lbc_nfd_nogather( ARRAY_IN(:,:,:,:,jf), ztabr(:,ij1:ij2,:,:), cd_nat LBC_ARG, psgn LBC_ARG ) 
     281         END DO 
     282         ! 
     283         DEALLOCATE( ztabr, ztabw, jj_s, jj_b, ipj_s ) 
     284         ! 
     285         DO jr = 1,nsndto 
     286            iproc = nfproc(isendto(jr)) 
     287            IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN 
     288               CALL mpi_wait( ml_req_nf(jr), ml_stat, ml_err )   ! put the wait at the very end just before the deallocate 
     289            ENDIF 
     290         END DO 
     291         DEALLOCATE( ztabb ) 
     292         ! 
     293      ELSE                             !==  allgather exchanges  ==! 
     294         ! 
     295         ! how many lines do we exchange at max? -> ipj    (no further optimizations in this case...) 
     296         ipj =      nn_hls + 2 
     297         ! how many lines do we     need at max? -> ipj2   (no further optimizations in this case...) 
     298         ipj2 = 2 * nn_hls + 2 
     299         ! 
     300         i0max = jpimax - 2 * nn_hls 
     301         ibuffsize = i0max * ipj * ipk * ipl * ipf 
     302         ALLOCATE( znorthloc(i0max,ipj,ipk,ipl,ipf), znorthglo(i0max,ipj,ipk,ipl,ipf,ndim_rank_north) ) 
     303         ! 
     304         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk               ! put in znorthloc ipj j-lines of ptab 
     305            DO jj = 1, ipj 
     306               ij2 = jpj - ipj2 + jj                        ! the first ipj lines of the last ipj2 lines 
     307               DO ji = 1, Ni_0 
     308                  ii2 = Nis0 - 1 + ji                       ! inner domain: Nis0 to Nie0 
     309                  znorthloc(ji,jj,jk,jl,jf) = ARRAY_IN(ii2,ij2,jk,jl,jf) 
     310               END DO 
     311               DO ji = Ni_0+1, i0max 
     312                  znorthloc(ji,jj,jk,jl,jf) = HUGEVAL(0.)   ! avoid sending uninitialized values (make sure we don't use it) 
    140313               END DO 
    141314            END DO 
    142          END DO 
    143          ! 
    144          ibuffsize = jpimax * ipf_j * ipk * ipl 
    145          ! 
    146          ALLOCATE( zfoldwk(jpimax,ipf_j,ipk,ipl,1) ) 
    147          ALLOCATE( ztabr(jpimax*jpmaxngh,ipj,ipk,ipl,ipf) )  
    148          ! when some processors of the north fold are suppressed,  
    149          ! values of ztab* arrays corresponding to these suppressed domain won't be defined  
    150          ! and we need a default definition to 0. 
    151          ! a better test should be: a testing if "suppressed land-processors" belongs to the north-pole folding 
    152          IF ( jpni*jpnj /= jpnij ) ztabr(:,:,:,:,:) = 0._wp 
    153          ! 
    154          DO jr = 1, nsndto 
    155             IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN 
    156                CALL mppsend( 5, znorthloc, ibuffsize, nfipproc(isendto(jr),jpnj), ml_req_nf(jr) ) 
    157             ENDIF 
    158          END DO 
    159          ! 
    160          DO jr = 1,nsndto 
    161             iproc = nfipproc(isendto(jr),jpnj) 
    162             IF(iproc /= -1) THEN 
    163                iilb = nimppt(iproc+1) 
    164                ilci = nlcit (iproc+1) 
    165                ildi = nldit (iproc+1) 
    166                ilei = nleit (iproc+1) 
    167                IF( iilb            ==      1 )   ildi = 1      ! e-w boundary already done -> force to take 1st column 
    168                IF( iilb + ilci - 1 == jpiglo )   ilei = ilci   ! e-w boundary already done -> force to take last column 
    169                iilb = nfiimpp(isendto(jr),jpnj) - nfiimpp(isendto(1),jpnj) 
    170             ENDIF 
    171             IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN 
    172                CALL mpprecv(5, zfoldwk, ibuffsize, iproc) 
    173                js = 0 
    174                DO jf = 1, ipf ; DO jj = 1, ipj_s(jf) 
    175                   js = js + 1 
    176                   DO jl = 1, ipl 
    177                      DO jk = 1, ipk 
    178                         DO ji = ildi, ilei 
    179                            ztabr(iilb+ji,jj,jk,jl,jf) = zfoldwk(ji,js,jk,jl,1) 
     315         END DO   ;   END DO   ;   END DO 
     316         ! 
     317         ! start waiting time measurement 
     318         IF( ln_timing ) CALL tic_tac(.TRUE.) 
     319         CALL MPI_ALLGATHER( znorthloc, ibuffsize, MPI_TYPE, znorthglo, ibuffsize, MPI_TYPE, ncomm_north, ierr ) 
     320         ! stop waiting time measurement 
     321         IF( ln_timing ) CALL tic_tac(.FALSE.) 
     322         DEALLOCATE( znorthloc ) 
     323         ALLOCATE( ztabglo(jpiglo,ipj2,ipk,ipl,ipf) ) 
     324         ! 
     325         ! need to fill only the first ipj lines of ztabglo as lbc_nfd don't use the last nn_hls lines 
     326         ijnr = 0 
     327         DO jr = 1, jpni                                                        ! recover the global north array 
     328            iproc = nfproc(jr) 
     329            impp  = nfimpp(jr) 
     330            ipi   = nfjpi( jr) - 2 * nn_hls                       ! corresponds to Ni_0 but for subdomain iproc 
     331            IF( iproc == -1 ) THEN   ! No neighbour (land proc that was suppressed) 
     332              ! 
     333               SELECT CASE ( kfillmode ) 
     334               CASE ( jpfillnothing )               ! no filling  
     335               CASE ( jpfillcopy    )               ! filling with inner domain values 
     336                  DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     337                     DO jj = 1, ipj 
     338                        ij2 = jpj - ipj2 + jj                    ! the first ipj lines of the last ipj2 lines 
     339                        DO ji = 1, ipi 
     340                           ii1 = impp + nn_hls + ji - 1          ! corresponds to mig(nn_hls + ji) but for subdomain iproc 
     341                           ztabglo(ii1,jj,jk,jl,jf) = ARRAY_IN(Nis0,ij2,jk,jl,jf)   ! chose to take the 1st iner domain point 
    180342                        END DO 
    181343                     END DO 
     344                  END DO   ;   END DO   ;   END DO 
     345               CASE ( jpfillcst     )               ! filling with constant value 
     346                  DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     347                     DO jj = 1, ipj 
     348                        DO ji = 1, ipi 
     349                           ii1 = impp + nn_hls + ji - 1          ! corresponds to mig(nn_hls + ji) but for subdomain iproc 
     350                           ztabglo(ii1,jj,jk,jl,jf) = pfillval 
     351                        END DO 
     352                     END DO 
     353                 END DO   ;   END DO   ;   END DO 
     354               END SELECT 
     355               ! 
     356            ELSE 
     357               ijnr = ijnr + 1 
     358               DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk 
     359                  DO jj = 1, ipj 
     360                     DO ji = 1, ipi 
     361                        ii1 = impp + nn_hls + ji - 1             ! corresponds to mig(nn_hls + ji) but for subdomain iproc 
     362                        ztabglo(ii1,jj,jk,jl,jf) = znorthglo(ji,jj,jk,jl,jf,ijnr) 
     363                     END DO 
    182364                  END DO 
    183                END DO; END DO 
    184             ELSE IF( iproc == narea-1 ) THEN 
    185                DO jf = 1, ipf ; DO jj = 1, ipj_s(jf) 
    186                   DO jl = 1, ipl 
    187                      DO jk = 1, ipk 
    188                         DO ji = ildi, ilei 
    189                            ztabr(iilb+ji,jj,jk,jl,jf) = ARRAY_IN(ji,jj_s(jf,jj),jk,jl,jf) 
    190                         END DO 
    191                      END DO 
    192                   END DO 
    193                END DO; END DO 
    194             ENDIF 
    195          END DO 
    196          IF( l_isend ) THEN 
    197             DO jr = 1,nsndto 
    198                IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN 
    199                   CALL mpi_wait( ml_req_nf(jr), ml_stat, ml_err ) 
    200                ENDIF 
     365               END DO   ;   END DO   ;   END DO 
     366            ENDIF 
     367            ! 
     368         END DO   ! jpni 
     369         DEALLOCATE( znorthglo ) 
     370         ! 
     371         DO jf = 1, ipf 
     372            CALL lbc_nfd( ztabglo(:,:,:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG )   ! North fold boundary condition 
     373            DO jl = 1, ipl   ;   DO jk = 1, ipk                  ! e-w periodicity 
     374               DO jj = 1, nn_hls + 1 
     375                  ij1 = ipj2 - (nn_hls + 1) + jj                 ! need only the last nn_hls + 1 lines until ipj2 
     376                  ztabglo(              1:nn_hls,ij1,jk,jl,jf) = ztabglo(jpiglo-2*nn_hls+1:jpiglo-nn_hls,ij1,jk,jl,jf) 
     377                  ztabglo(jpiglo-nn_hls+1:jpiglo,ij1,jk,jl,jf) = ztabglo(         nn_hls+1:     2*nn_hls,ij1,jk,jl,jf) 
     378               END DO 
     379            END DO   ;   END DO 
     380         END DO      
     381         ! 
     382         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk               ! Scatter back to ARRAY_IN 
     383            DO jj = 1, nn_hls + 1 
     384               ij1 = jpj  - (nn_hls + 1) + jj   ! last nn_hls + 1 lines until jpj 
     385               ij2 = ipj2 - (nn_hls + 1) + jj   ! last nn_hls + 1 lines until ipj2 
     386               DO ji= 1, jpi 
     387                  ii2 = mig(ji) 
     388                  ARRAY_IN(ji,ij1,jk,jl,jf) = ztabglo(ii2,ij2,jk,jl,jf) 
     389               END DO 
    201390            END DO 
    202          ENDIF 
    203          ! 
    204          ! North fold boundary condition 
    205          ! 
    206          DO jf = 1, ipf 
    207             CALL lbc_nfd_nogather(ARRAY_IN(:,:,:,:,jf), ztabr(:,1:ipj_s(jf),:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG ) 
    208          END DO 
    209          ! 
    210          DEALLOCATE( zfoldwk ) 
    211          DEALLOCATE( ztabr )  
    212          DEALLOCATE( jj_s )  
    213          DEALLOCATE( ipj_s )  
    214       ELSE                             !==  ????  ==! 
    215          ! 
    216          ipj   = 4            ! 2nd dimension of message transfers (last j-lines) 
    217          ! 
    218          ALLOCATE( znorthloc(jpimax,ipj,ipk,ipl,ipf) ) 
    219          ! 
    220          DO jf = 1, ipf                ! put in znorthloc the last ipj j-lines of ptab 
    221             DO jl = 1, ipl 
    222                DO jk = 1, ipk 
    223                   DO jj = nlcj - ipj +1, nlcj 
    224                      ij = jj - nlcj + ipj 
    225                      znorthloc(1:jpi,ij,jk,jl,jf) = ARRAY_IN(1:jpi,jj,jk,jl,jf) 
    226                   END DO 
    227                END DO 
    228             END DO 
    229          END DO 
    230          ! 
    231          ibuffsize = jpimax * ipj * ipk * ipl * ipf 
    232          ! 
    233          ALLOCATE( ztab       (jpiglo,ipj,ipk,ipl,ipf     ) ) 
    234          ALLOCATE( znorthgloio(jpimax,ipj,ipk,ipl,ipf,jpni) ) 
    235          ! 
    236          ! when some processors of the north fold are suppressed, 
    237          ! values of ztab* arrays corresponding to these suppressed domain won't be defined 
    238          ! and we need a default definition to 0. 
    239          ! a better test should be: a testing if "suppressed land-processors" belongs to the north-pole folding 
    240          IF ( jpni*jpnj /= jpnij ) ztab(:,:,:,:,:) = 0._wp 
    241          ! 
    242          CALL MPI_ALLGATHER( znorthloc  , ibuffsize, MPI_DOUBLE_PRECISION,                & 
    243             &                znorthgloio, ibuffsize, MPI_DOUBLE_PRECISION, ncomm_north, ierr ) 
    244          ! 
    245          ! 
    246          DO jr = 1, ndim_rank_north         ! recover the global north array 
    247             iproc = nrank_north(jr) + 1 
    248             iilb  = nimppt(iproc) 
    249             ilci  = nlcit (iproc) 
    250             ildi  = nldit (iproc) 
    251             ilei  = nleit (iproc) 
    252             IF( iilb            ==      1 )   ildi = 1      ! e-w boundary already done -> force to take 1st column 
    253             IF( iilb + ilci - 1 == jpiglo )   ilei = ilci   ! e-w boundary already done -> force to take last column 
    254             DO jf = 1, ipf 
    255                DO jl = 1, ipl 
    256                   DO jk = 1, ipk 
    257                      DO jj = 1, ipj 
    258                         DO ji = ildi, ilei 
    259                            ztab(ji+iilb-1,jj,jk,jl,jf) = znorthgloio(ji,jj,jk,jl,jf,jr) 
    260                         END DO 
    261                      END DO 
    262                   END DO 
    263                END DO 
    264             END DO 
    265          END DO 
    266          DO jf = 1, ipf 
    267             CALL lbc_nfd( ztab(:,:,:,:,jf), cd_nat LBC_ARG, psgn LBC_ARG )   ! North fold boundary condition 
    268          END DO 
    269          ! 
    270          DO jf = 1, ipf 
    271             DO jl = 1, ipl 
    272                DO jk = 1, ipk 
    273                   DO jj = nlcj-ipj+1, nlcj             ! Scatter back to ARRAY_IN 
    274                      ij = jj - nlcj + ipj 
    275                      DO ji= 1, nlci 
    276                         ARRAY_IN(ji,jj,jk,jl,jf) = ztab(ji+nimpp-1,ij,jk,jl,jf) 
    277                      END DO 
    278                   END DO 
    279                END DO 
    280             END DO 
    281          END DO 
    282          ! 
    283       ! 
    284          DEALLOCATE( ztab ) 
    285          DEALLOCATE( znorthgloio ) 
    286       ENDIF 
    287       ! 
    288       DEALLOCATE( znorthloc ) 
     391         END DO   ;   END DO   ;   END DO 
     392         ! 
     393         DEALLOCATE( ztabglo ) 
     394         ! 
     395      ENDIF   ! l_north_nogather 
    289396      ! 
    290397   END SUBROUTINE ROUTINE_NFD 
    291398 
     399#undef PRECISION 
     400#undef MPI_TYPE 
     401#undef SENDROUTINE 
     402#undef RECVROUTINE 
    292403#undef ARRAY_TYPE 
    293404#undef NAT_IN 
     
    298409#undef F_SIZE 
    299410#undef LBC_ARG 
     411#undef HUGEVAL 
  • utils/tools/DOMAINcfg/src/mppini.F90

    r13204 r14623  
    88   !!            8.0  !  1998-05  (M. Imbard, J. Escobar, L. Colombet )  SHMEM and MPI versions 
    99   !!  NEMO      1.0  !  2004-01  (G. Madec, J.M Molines)  F90 : free form , north fold jpni > 1 
    10    !!            3.4  ! 2011-10  (A. C. Coward, NOCS & J. Donners, PRACE) add mpp_init_nfdcom 
    11    !!            3.   ! 2013-06  (I. Epicoco, S. Mocavero, CMCC) mpp_init_nfdcom: setup avoiding MPI communication  
     10   !!            3.4  !  2011-10  (A. C. Coward, NOCS & J. Donners, PRACE)  add init_nfdcom 
     11   !!            3.   !  2013-06  (I. Epicoco, S. Mocavero, CMCC)  init_nfdcom: setup avoiding MPI communication  
    1212   !!            4.0  !  2016-06  (G. Madec)  use domain configuration file instead of bathymetry file 
    1313   !!            4.0  !  2017-06  (J.M. Molines, T. Lovato) merge of mppini and mppini_2 
     
    1515 
    1616   !!---------------------------------------------------------------------- 
    17    !!  mpp_init          : Lay out the global domain over processors with/without land processor elimination 
    18    !!  mpp_init_mask     : Read global bathymetric information to facilitate land suppression 
    19    !!  mpp_init_partition: Calculate MPP domain decomposition 
    20    !!  factorise         : Calculate the factors of the no. of MPI processes 
    21    !!  mpp_init_nfdcom   : Setup for north fold exchanges with explicit point-to-point messaging 
     17   !!  mpp_init       : Lay out the global domain over processors with/without land processor elimination 
     18   !!      init_ioipsl: IOIPSL initialization in mpp  
     19   !!      init_nfdcom: Setup for north fold exchanges with explicit point-to-point messaging 
     20   !!      init_doloop: set the starting/ending indices of DO-loop used in do_loop_substitute  
    2221   !!---------------------------------------------------------------------- 
    2322   USE dom_oce        ! ocean space and time domain 
     23   ! USE bdy_oce        ! open BounDarY   
    2424   ! 
    25    USE lbcnfd  , ONLY : isendto, nsndto, nfsloop, nfeloop  ! Setup of north fold exchanges  
     25   USE lbcnfd  , ONLY : isendto, nsndto ! Setup of north fold exchanges  
    2626   USE lib_mpp        ! distribued memory computing library 
    2727   USE iom            ! nemo I/O library  
     
    3232   PRIVATE 
    3333 
    34    PUBLIC mpp_init       ! called by opa.F90 
    35  
    36    INTEGER :: numbot = -1  ! 'bottom_level' local logical unit 
     34   PUBLIC   mpp_init       ! called by nemogcm.F90 
     35   PUBLIC   mpp_getnum     ! called by prtctl 
     36   PUBLIC   mpp_basesplit  ! called by prtctl 
     37   PUBLIC   mpp_is_ocean   ! called by prtctl 
     38    
     39   INTEGER ::   numbot = -1   ! 'bottom_level' local logical unit 
     40   INTEGER ::   numbdy = -1   ! 'bdy_msk'      local logical unit 
    3741    
    3842   !!---------------------------------------------------------------------- 
    3943   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    40    !! $Id: mppini.F90 10570 2019-01-24 15:14:49Z acc $  
     44   !! $Id: mppini.F90 13305 2020-07-14 17:12:25Z acc $  
    4145   !! Software governed by the CeCILL license (see ./LICENSE) 
    4246   !!---------------------------------------------------------------------- 
     
    5862      !!---------------------------------------------------------------------- 
    5963      ! 
     64      jpiglo = Ni0glo 
     65      jpjglo = Nj0glo 
    6066      jpimax = jpiglo 
    6167      jpjmax = jpjglo 
     
    6369      jpj    = jpjglo 
    6470      jpk    = jpkglo 
    65       jpim1  = jpi-1                                            ! inner domain indices 
    66       jpjm1  = jpj-1                                            !   "           " 
    67       jpkm1  = MAX( 1, jpk-1 )                                  !   "           " 
     71      jpim1  = jpi-1                         ! inner domain indices 
     72      jpjm1  = jpj-1                         !   "           " 
     73      jpkm1  = MAX( 1, jpk-1 )               !   "           " 
     74      ! 
     75      CALL init_doloop                       ! set start/end indices or do-loop depending on the halo width value (nn_hls)  
     76      ! 
    6877      jpij   = jpi*jpj 
    6978      jpni   = 1 
    7079      jpnj   = 1 
    7180      jpnij  = jpni*jpnj 
    72       nimpp  = 1           !  
     81      nn_hls = 1 
     82      nimpp  = 1 
    7383      njmpp  = 1 
    74       nlci   = jpi 
    75       nlcj   = jpj 
    76       nldi   = 1 
    77       nldj   = 1 
    78       nlei   = jpi 
    79       nlej   = jpj 
    8084      nbondi = 2 
    8185      nbondj = 2 
    82       npolj = jperio 
     86      nidom  = FLIO_DOM_NONE 
     87      npolj = 0 
     88      IF( jperio == 3 .OR. jperio == 4 )   npolj = 3 
     89      IF( jperio == 5 .OR. jperio == 6 )   npolj = 5 
    8390      l_Iperio = jpni == 1 .AND. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6 .OR. jperio == 7) 
    8491      l_Jperio = jpnj == 1 .AND. (jperio == 2 .OR. jperio == 7) 
     
    95102         CALL ctl_stop( 'mpp_init: equality  jpni = jpnj = jpnij = 1 is not satisfied',   & 
    96103            &           'the domain is lay out for distributed memory computing!' ) 
    97  
     104         ! 
    98105#if defined key_agrif 
    99      IF (.not.agrif_root()) THEN 
    100         CALL agrif_nemo_init 
    101      ENDIF 
     106      CALL agrif_nemo_init() 
    102107 
    103108      IF( .NOT. Agrif_Root() ) THEN       ! AGRIF children: specific setting (cf. agrif_user.F90) 
    104109         print *,'nbcellsx = ',nbcellsx,nbghostcells_x 
    105110         print *,'nbcellsy = ',nbcellsy,nbghostcells_y_s,nbghostcells_y_n 
    106          IF( jpiglo /= nbcellsx + 2 + 2*nbghostcells_x ) THEN 
     111         IF( Ni0glo /= nbcellsx + 2 + 2*nbghostcells_x ) THEN 
    107112            IF(lwp) THEN 
    108113               WRITE(numout,*) 
    109                WRITE(numout,*) 'jpiglo should be: ', nbcellsx + 2 + 2*nbghostcells_x 
     114               WRITE(numout,*) 'Ni0glo should be: ', nbcellsx + 2 + 2*nbghostcells_x 
    110115            ENDIF         
    111             CALL ctl_stop( 'STOP', 'mpp_init: Agrif children requires jpiglo == nbcellsx + 2 + 2*nbghostcells_x' ) 
     116            CALL ctl_stop( 'STOP', 'mpp_init: Agrif children requires Ni0glo == nbcellsx + 2 + 2*nbghostcells_x' ) 
    112117         ENDIF    
    113          IF( jpjglo /= nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n ) THEN 
     118         IF( Nj0glo /= nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n ) THEN 
    114119            IF(lwp) THEN 
    115120               WRITE(numout,*) 
    116                WRITE(numout,*) 'jpjglo shoud be: ', nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n 
     121               WRITE(numout,*) 'Nj0glo shoud be: ', nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n 
    117122            ENDIF         
    118123            CALL ctl_stop( 'STOP', & 
    119                 'mpp_init: Agrif children requires jpjglo == nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n' ) 
     124                'mpp_init: Agrif children requires Nj0glo == nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n' ) 
    120125         ENDIF    
    121126         IF( ln_use_jattr )   CALL ctl_stop( 'STOP', 'mpp_init:Agrif children requires ln_use_jattr = .false. ' ) 
    122       ENDIF 
     127    ENDIF 
    123128#endif 
    124          ! 
    125129   END SUBROUTINE mpp_init 
    126130 
     
    151155      !!                    njmpp     : latitudinal  index 
    152156      !!                    narea     : number for local area 
    153       !!                    nlci      : first dimension 
    154       !!                    nlcj      : second dimension 
    155157      !!                    nbondi    : mark for "east-west local boundary" 
    156158      !!                    nbondj    : mark for "north-south local boundary" 
     
    163165      INTEGER ::   ji, jj, jn, jproc, jarea   ! dummy loop indices 
    164166      INTEGER ::   inijmin 
    165       INTEGER ::   i2add 
    166167      INTEGER ::   inum                       ! local logical unit 
    167       INTEGER ::   idir, ifreq, icont         ! local integers 
     168      INTEGER ::   idir, ifreq                ! local integers 
    168169      INTEGER ::   ii, il1, ili, imil         !   -       - 
    169170      INTEGER ::   ij, il2, ilj, ijm1         !   -       - 
     
    173174      INTEGER ::   ierr, ios                  !  
    174175      INTEGER ::   inbi, inbj, iimax,  ijmax, icnt1, icnt2 
    175       LOGICAL ::   llbest 
     176      LOGICAL ::   llbest, llauto 
    176177      LOGICAL ::   llwrtlay 
     178      LOGICAL ::   ln_listonly 
    177179      INTEGER, ALLOCATABLE, DIMENSION(:)     ::   iin, ii_nono, ii_noea          ! 1D workspace 
    178180      INTEGER, ALLOCATABLE, DIMENSION(:)     ::   ijn, ii_noso, ii_nowe          !  -     - 
    179       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ilci, ibondi, ipproc   ! 2D workspace 
    180       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ilcj, ibondj, ipolj    !  -     - 
    181       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ilei, ildi, iono, ioea         !  -     - 
    182       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ilej, ildj, ioso, iowe         !  -     - 
     181      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ijpi, ibondi, ipproc   ! 2D workspace 
     182      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ijpj, ibondj, ipolj    !  -     - 
     183      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iie0, iis0, iono, ioea         !  -     - 
     184      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ije0, ijs0, ioso, iowe         !  -     - 
    183185      LOGICAL, ALLOCATABLE, DIMENSION(:,:) ::   llisoce                        !  -     - 
    184       !!---------------------------------------------------------------------- 
    185  
    186       llwrtlay = lwp  
     186!      NAMELIST/nambdy/ ln_bdy, nb_bdy, ln_coords_file, cn_coords_file,           & 
     187!           &             ln_mask_file, cn_mask_file, cn_dyn2d, nn_dyn2d_dta,     & 
     188!           &             cn_dyn3d, nn_dyn3d_dta, cn_tra, nn_tra_dta,             &   
     189!           &             ln_tra_dmp, ln_dyn3d_dmp, rn_time_dmp, rn_time_dmp_out, & 
     190!           &             cn_ice, nn_ice_dta,                                     & 
     191!           &             ln_vol, nn_volctl, nn_rimwidth 
     192      NAMELIST/nammpp/ jpni, jpnj, nn_hls, ln_nnogather, ln_listonly 
     193      !!---------------------------------------------------------------------- 
     194      ! 
     195      llwrtlay = lwm .OR. sn_cfctl%l_layout 
     196      ! 
     197      !  0. read namelists parameters 
     198      ! ----------------------------------- 
     199      ! 
     200      READ  ( numnam_ref, nammpp, IOSTAT = ios, ERR = 901 ) 
     201901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'nammpp in reference namelist' ) 
     202      READ  ( numnam_cfg, nammpp, IOSTAT = ios, ERR = 902 ) 
     203902   IF( ios >  0 )   CALL ctl_nam ( ios , 'nammpp in configuration namelist' )    
     204      ! 
     205      nn_hls = MAX(1, nn_hls)   ! nn_hls must be > 0 
     206      IF(lwp) THEN 
     207            WRITE(numout,*) '   Namelist nammpp' 
     208         IF( jpni < 1 .OR. jpnj < 1  ) THEN 
     209            WRITE(numout,*) '      jpni and jpnj will be calculated automatically' 
     210         ELSE 
     211            WRITE(numout,*) '      processor grid extent in i                            jpni = ', jpni 
     212            WRITE(numout,*) '      processor grid extent in j                            jpnj = ', jpnj 
     213         ENDIF 
     214            WRITE(numout,*) '      avoid use of mpi_allgather at the north fold  ln_nnogather = ', ln_nnogather 
     215            WRITE(numout,*) '      halo width (applies to both rows and columns)       nn_hls = ', nn_hls 
     216      ENDIF 
     217      ! 
     218      IF(lwm)   WRITE( numond, nammpp ) 
     219      ! 
     220!!!------------------------------------ 
     221!!!  nn_hls shloud be read in nammpp 
     222!!!------------------------------------ 
     223      jpiglo = Ni0glo + 2 * nn_hls 
     224      jpjglo = Nj0glo + 2 * nn_hls 
     225      ! 
     226      ! do we need to take into account bdy_msk? 
     227!      READ  ( numnam_ref, nambdy, IOSTAT = ios, ERR = 903) 
     228!903   IF( ios /= 0 )   CALL ctl_nam ( ios , 'nambdy in reference namelist (mppini)' ) 
     229!      READ  ( numnam_cfg, nambdy, IOSTAT = ios, ERR = 904 ) 
     230!904   IF( ios >  0 )   CALL ctl_nam ( ios , 'nambdy in configuration namelist (mppini)' ) 
    187231      ! 
    188232      IF(               ln_read_cfg ) CALL iom_open( cn_domcfg,    numbot ) 
     233!      IF( ln_bdy .AND. ln_mask_file ) CALL iom_open( cn_mask_file, numbdy ) 
     234      ! 
     235      IF( ln_listonly )   CALL bestpartition( MAX(mppsize,jpni*jpnj), ldlist = .TRUE. )   ! must be done by all core 
    189236      ! 
    190237      !  1. Dimension arrays for subdomains 
    191238      ! ----------------------------------- 
    192239      ! 
    193       ! If dimensions of processor grid weren't specified in the namelist file 
     240      ! If dimensions of processors grid weren't specified in the namelist file 
    194241      ! then we calculate them here now that we have our communicator size 
     242      IF(lwp) THEN 
     243         WRITE(numout,*) 'mpp_init:' 
     244         WRITE(numout,*) '~~~~~~~~ ' 
     245         WRITE(numout,*) 
     246      ENDIF 
    195247      IF( jpni < 1 .OR. jpnj < 1 ) THEN 
    196          CALL mpp_init_bestpartition( mppsize, jpni, jpnj ) 
     248         CALL bestpartition( mppsize, jpni, jpnj )           ! best mpi decomposition for mppsize mpi processes 
     249         llauto = .TRUE. 
    197250         llbest = .TRUE. 
    198251      ELSE 
    199          CALL mpp_init_bestpartition( mppsize, inbi, inbj, icnt2 ) 
    200          CALL mpp_basic_decomposition( jpni, jpnj, jpimax, jpjmax ) 
    201          CALL mpp_basic_decomposition( inbi, inbj,  iimax,  ijmax ) 
    202          IF( iimax*ijmax < jpimax*jpjmax ) THEN 
     252         llauto = .FALSE. 
     253         CALL bestpartition( mppsize, inbi, inbj, icnt2 )    ! best mpi decomposition for mppsize mpi processes 
     254         ! largest subdomain size for mpi decoposition jpni*jpnj given in the namelist 
     255         CALL mpp_basesplit( jpiglo, jpjglo, nn_hls, jpni, jpnj, jpimax, jpjmax ) 
     256         ! largest subdomain size for mpi decoposition inbi*inbj given by bestpartition 
     257         CALL mpp_basesplit( jpiglo, jpjglo, nn_hls, inbi, inbj,  iimax,  ijmax ) 
     258         icnt1 = jpni*jpnj - mppsize   ! number of land subdomains that should be removed to use mppsize mpi processes 
     259         IF(lwp) THEN 
     260            WRITE(numout,9000) '   The chosen domain decomposition ', jpni, ' x ', jpnj, ' with ', icnt1, ' land subdomains' 
     261            WRITE(numout,9002) '      - uses a total of ',  mppsize,' mpi process' 
     262            WRITE(numout,9000) '      - has mpi subdomains with a maximum size of (jpi = ', jpimax, ', jpj = ', jpjmax,   & 
     263               &                                                                ', jpi*jpj = ', jpimax*jpjmax, ')' 
     264            WRITE(numout,9000) '   The best domain decompostion ', inbi, ' x ', inbj, ' with ', icnt2, ' land subdomains' 
     265            WRITE(numout,9002) '      - uses a total of ',  inbi*inbj-icnt2,' mpi process' 
     266            WRITE(numout,9000) '      - has mpi subdomains with a maximum size of (jpi = ',  iimax, ', jpj = ',  ijmax,   & 
     267               &                                                             ', jpi*jpj = ',  iimax* ijmax, ')' 
     268         ENDIF 
     269         IF( iimax*ijmax < jpimax*jpjmax ) THEN   ! chosen subdomain size is larger that the best subdomain size 
    203270            llbest = .FALSE. 
    204             icnt1 = jpni*jpnj - mppsize 
    205             WRITE(ctmp1,9000) '   The chosen domain decomposition ', jpni, ' x ', jpnj, ' with ', icnt1, ' land sub-domains' 
    206             WRITE(ctmp2,9000) '   has larger MPI subdomains (jpi = ', jpimax, ', jpj = ', jpjmax, ', jpi*jpj = ', jpimax*jpjmax, ')' 
    207             WRITE(ctmp3,9000) '   than the following domain decompostion ', inbi, ' x ', inbj, ' with ', icnt2, ' land sub-domains' 
    208             WRITE(ctmp4,9000) '   which MPI subdomains size is jpi = ', iimax, ', jpj = ', ijmax, ', jpi*jpj = ', iimax*ijmax, ' ' 
    209             CALL ctl_warn( 'mpp_init:', '~~~~~~~~ ', ctmp1, ctmp2, ctmp3, ctmp4, ' ', '    --- YOU ARE WASTING CPU... ---', ' ' ) 
     271            IF ( inbi*inbj-icnt2 < mppsize ) THEN 
     272               WRITE(ctmp1,*) '   ==> You could therefore have smaller mpi subdomains with less mpi processes' 
     273            ELSE 
     274               WRITE(ctmp1,*) '   ==> You could therefore have smaller mpi subdomains with the same number of mpi processes' 
     275            ENDIF 
     276            CALL ctl_warn( ' ', ctmp1, ' ', '    ---   YOU ARE WASTING CPU...   ---', ' ' ) 
     277         ELSE IF ( iimax*ijmax == jpimax*jpjmax .AND. (inbi*inbj-icnt2) <  mppsize) THEN 
     278            llbest = .FALSE. 
     279            WRITE(ctmp1,*) '   ==> You could therefore have the same mpi subdomains size with less mpi processes' 
     280            CALL ctl_warn( ' ', ctmp1, ' ', '    ---   YOU ARE WASTING CPU...   ---', ' ' ) 
    210281         ELSE 
    211282            llbest = .TRUE. 
     
    215286      ! look for land mpi subdomains... 
    216287      ALLOCATE( llisoce(jpni,jpnj) ) 
    217       CALL mpp_init_isoce( jpni, jpnj, llisoce ) 
     288      CALL mpp_is_ocean( llisoce ) 
    218289      inijmin = COUNT( llisoce )   ! number of oce subdomains 
    219290 
    220       IF( mppsize < inijmin ) THEN 
     291      IF( mppsize < inijmin ) THEN   ! too many oce subdomains: can happen only if jpni and jpnj are prescribed... 
    221292         WRITE(ctmp1,9001) '   With this specified domain decomposition: jpni = ', jpni, ' jpnj = ', jpnj 
    222293         WRITE(ctmp2,9002) '   we can eliminate only ', jpni*jpnj - inijmin, ' land mpi subdomains therefore ' 
    223294         WRITE(ctmp3,9001) '   the number of ocean mpi subdomains (', inijmin,') exceed the number of MPI processes:', mppsize 
    224295         WRITE(ctmp4,*) '   ==>>> There is the list of best domain decompositions you should use: ' 
    225          CALL ctl_stop( 'mpp_init:', '~~~~~~~~ ', ctmp1, ctmp2, ctmp3, ctmp4 ) 
    226          CALL mpp_init_bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
    227          CALL ctl_stop( 'STOP' ) 
    228       ENDIF 
    229  
    230       IF( mppsize > jpni*jpnj ) THEN 
    231          WRITE(ctmp1,9003) '   The number of mpi processes: ', mppsize 
    232          WRITE(ctmp2,9003) '   exceeds the maximum number of subdomains (ocean+land) = ', jpni*jpnj 
    233          WRITE(ctmp3,9001) '   defined by the following domain decomposition: jpni = ', jpni, ' jpnj = ', jpnj 
    234          WRITE(ctmp4,*) '   ==>>> There is the list of best domain decompositions you should use: ' 
    235          CALL ctl_stop( 'mpp_init:', '~~~~~~~~ ', ctmp1, ctmp2, ctmp3, ctmp4 ) 
    236          CALL mpp_init_bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
    237          CALL ctl_stop( 'STOP' ) 
     296         CALL ctl_stop( ctmp1, ctmp2, ctmp3, ' ', ctmp4, ' ' ) 
     297         CALL bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
     298      ENDIF 
     299 
     300      IF( mppsize > jpni*jpnj ) THEN   ! not enough mpi subdomains for the total number of mpi processes 
     301         IF(lwp) THEN 
     302            WRITE(numout,9003) '   The number of mpi processes: ', mppsize 
     303            WRITE(numout,9003) '   exceeds the maximum number of subdomains (ocean+land) = ', jpni*jpnj 
     304            WRITE(numout,9001) '   defined by the following domain decomposition: jpni = ', jpni, ' jpnj = ', jpnj 
     305            WRITE(numout,   *) '   You should: ' 
     306           IF( llauto ) THEN 
     307               WRITE(numout,*) '     - either prescribe your domain decomposition with the namelist variables' 
     308               WRITE(numout,*) '       jpni and jpnj to match the number of mpi process you want to use, ' 
     309               WRITE(numout,*) '       even IF it not the best choice...' 
     310               WRITE(numout,*) '     - or keep the automatic and optimal domain decomposition by picking up one' 
     311               WRITE(numout,*) '       of the number of mpi process proposed in the list bellow' 
     312            ELSE 
     313               WRITE(numout,*) '     - either properly prescribe your domain decomposition with jpni and jpnj' 
     314               WRITE(numout,*) '       in order to be consistent with the number of mpi process you want to use' 
     315               WRITE(numout,*) '       even IF it not the best choice...' 
     316               WRITE(numout,*) '     - or use the automatic and optimal domain decomposition and pick up one of' 
     317               WRITE(numout,*) '       the domain decomposition proposed in the list bellow' 
     318            ENDIF 
     319            WRITE(numout,*) 
     320         ENDIF 
     321         CALL bestpartition( mppsize, ldlist = .TRUE. )   ! must be done by all core 
    238322      ENDIF 
    239323 
     
    244328         WRITE(ctmp3,9002) '   we suppressed ', jpni*jpnj - mppsize, ' land subdomains ' 
    245329         WRITE(ctmp4,9002) '   BUT we had to keep ', mppsize - inijmin, ' land subdomains that are useless...' 
    246          CALL ctl_warn( 'mpp_init:', '~~~~~~~~ ', ctmp1, ctmp2, ctmp3, ctmp4, ' ', '    --- YOU ARE WASTING CPU... ---', ' ' ) 
     330         CALL ctl_warn( ctmp1, ctmp2, ctmp3, ctmp4, ' ', '    --- YOU ARE WASTING CPU... ---', ' ' ) 
    247331      ELSE   ! mppsize = inijmin 
    248332         IF(lwp) THEN 
    249             IF(llbest) WRITE(numout,*) 'mpp_init: You use an optimal domain decomposition' 
    250             WRITE(numout,*) '~~~~~~~~ ' 
     333            IF(llbest) WRITE(numout,*) '   ==> you use the best mpi decomposition' 
     334            WRITE(numout,*) 
    251335            WRITE(numout,9003) '   Number of mpi processes: ', mppsize 
    252336            WRITE(numout,9003) '   Number of ocean subdomains = ', inijmin 
     
    2603449003  FORMAT (a, i5) 
    261345 
    262       IF( numbot /= -1 )   CALL iom_close( numbot ) 
    263      
    264       ALLOCATE(  nfiimpp(jpni,jpnj), nfipproc(jpni,jpnj), nfilcit(jpni,jpnj) ,    & 
    265          &       nimppt(jpnij) , ibonit(jpnij) , nlcit(jpnij) , nlcjt(jpnij) ,    & 
    266          &       njmppt(jpnij) , ibonjt(jpnij) , nldit(jpnij) , nldjt(jpnij) ,    & 
    267          &                                       nleit(jpnij) , nlejt(jpnij) ,    & 
     346      ALLOCATE(  nfimpp(jpni ) , nfproc(jpni ) ,   nfjpi(jpni ) ,                     & 
     347         &       nimppt(jpnij) , ibonit(jpnij) ,  jpiall(jpnij) ,  jpjall(jpnij) ,    & 
     348         &       njmppt(jpnij) , ibonjt(jpnij) , nis0all(jpnij) , njs0all(jpnij) ,    & 
     349         &                                       nie0all(jpnij) , nje0all(jpnij) ,    & 
    268350         &       iin(jpnij), ii_nono(jpnij), ii_noea(jpnij),   & 
    269351         &       ijn(jpnij), ii_noso(jpnij), ii_nowe(jpnij),   & 
    270          &       iimppt(jpni,jpnj), ilci(jpni,jpnj), ibondi(jpni,jpnj), ipproc(jpni,jpnj),   & 
    271          &       ijmppt(jpni,jpnj), ilcj(jpni,jpnj), ibondj(jpni,jpnj), ipolj(jpni,jpnj),   & 
    272          &       ilei(jpni,jpnj), ildi(jpni,jpnj), iono(jpni,jpnj), ioea(jpni,jpnj),   & 
    273          &       ilej(jpni,jpnj), ildj(jpni,jpnj), ioso(jpni,jpnj), iowe(jpni,jpnj),   & 
     352         &       iimppt(jpni,jpnj), ijpi(jpni,jpnj), ibondi(jpni,jpnj), ipproc(jpni,jpnj),   & 
     353         &       ijmppt(jpni,jpnj), ijpj(jpni,jpnj), ibondj(jpni,jpnj), ipolj(jpni,jpnj),   & 
     354         &         iie0(jpni,jpnj), iis0(jpni,jpnj),   iono(jpni,jpnj),  ioea(jpni,jpnj),   & 
     355         &         ije0(jpni,jpnj), ijs0(jpni,jpnj),   ioso(jpni,jpnj),  iowe(jpni,jpnj),   & 
    274356         &       STAT=ierr ) 
    275357      CALL mpp_sum( 'mppini', ierr ) 
     
    277359       
    278360#if defined key_agrif 
     361      CALL agrif_nemo_init() 
    279362      IF( .NOT. Agrif_Root() ) THEN       ! AGRIF children: specific setting (cf. agrif_user.F90) 
    280          CALL agrif_nemo_init 
    281          IF( jpiglo /= nbcellsx + 2 + 2*nbghostcells_x ) THEN 
     363         IF( Ni0glo /= nbcellsx + 2 + 2*nbghostcells_x ) THEN 
    282364            IF(lwp) THEN 
    283365               WRITE(numout,*) 
    284                WRITE(numout,*) 'jpiglo should be: ', nbcellsx + 2 + 2*nbghostcells_x 
     366               WRITE(numout,*) 'Ni0glo should be: ', nbcellsx + 2 + 2*nbghostcells_x 
    285367            ENDIF         
    286             CALL ctl_stop( 'STOP', 'mpp_init: Agrif children requires jpiglo == nbcellsx + 2 + 2*nbghostcells' ) 
     368            CALL ctl_stop( 'STOP', 'mpp_init: Agrif children requires Ni0glo == nbcellsx + 2 + 2*nbghostcells_x' ) 
    287369         ENDIF    
    288          IF( jpjglo /= nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n ) THEN 
     370         IF( Nj0glo /= nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n ) THEN 
    289371            IF(lwp) THEN 
    290372               WRITE(numout,*) 
    291                WRITE(numout,*) 'jpjglo shoud be: ', nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n 
     373               WRITE(numout,*) 'Nj0glo shoud be: ', nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n 
    292374            ENDIF         
    293375            CALL ctl_stop( 'STOP', & 
    294                'mpp_init: Agrif children requires jpjglo == nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n' ) 
     376               'mpp_init: Agrif children requires Nj0glo == nbcellsy + 2 + nbghostcells_y_s + nbghostcells_y_n' ) 
    295377         ENDIF    
    296378         IF( ln_use_jattr )   CALL ctl_stop( 'STOP', 'mpp_init:Agrif children requires ln_use_jattr = .false. ' ) 
     
    301383      ! ----------------------------------- 
    302384      ! 
    303       nreci = 2 * nn_hls 
    304       nrecj = 2 * nn_hls 
    305       CALL mpp_basic_decomposition( jpni, jpnj, jpimax, jpjmax, iimppt, ijmppt, ilci, ilcj ) 
    306       nfiimpp(:,:) = iimppt(:,:) 
    307       nfilcit(:,:) = ilci(:,:) 
     385 
     386      CALL mpp_basesplit( jpiglo, jpjglo, nn_hls, jpni, jpnj, jpimax, jpjmax, iimppt, ijmppt, ijpi, ijpj ) 
     387      CALL mpp_getnum( llisoce, ipproc, iin, ijn ) 
     388      ! 
     389      !DO jn = 1, jpni 
     390      !   jproc = ipproc(jn,jpnj) 
     391      !   ii = iin(jproc+1) 
     392      !   ij = ijn(jproc+1) 
     393      !   nfproc(jn) = jproc 
     394      !   nfimpp(jn) = iimppt(ii,ij) 
     395      !   nfjpi (jn) =   ijpi(ii,ij) 
     396      !END DO 
     397      nfproc(:) = ipproc(:,jpnj)  
     398      nfimpp(:) = iimppt(:,jpnj)  
     399      nfjpi (:) =   ijpi(:,jpnj) 
    308400      ! 
    309401      IF(lwp) THEN 
     
    314406         WRITE(numout,*) '      jpni = ', jpni   
    315407         WRITE(numout,*) '      jpnj = ', jpnj 
     408         WRITE(numout,*) '     jpnij = ', jpnij 
    316409         WRITE(numout,*) 
    317          WRITE(numout,*) '      sum ilci(i,1) = ', sum(ilci(:,1)), ' jpiglo = ', jpiglo 
    318          WRITE(numout,*) '      sum ilcj(1,j) = ', sum(ilcj(1,:)), ' jpjglo = ', jpjglo 
     410         WRITE(numout,*) '      sum ijpi(i,1) = ', sum(ijpi(:,1)), ' jpiglo = ', jpiglo 
     411         WRITE(numout,*) '      sum ijpj(1,j) = ', sum(ijpj(1,:)), ' jpjglo = ', jpjglo 
    319412      ENDIF 
    320413      
     
    331424         ii = 1 + MOD(iarea0,jpni) 
    332425         ij = 1 +     iarea0/jpni 
    333          ili = ilci(ii,ij) 
    334          ilj = ilcj(ii,ij) 
     426         ili = ijpi(ii,ij) 
     427         ilj = ijpj(ii,ij) 
    335428         ibondi(ii,ij) = 0                         ! default: has e-w neighbours 
    336429         IF( ii   ==    1 )   ibondi(ii,ij) = -1   ! first column, has only e neighbour 
     
    347440         ioea(ii,ij) = iarea0 + 1 
    348441         iono(ii,ij) = iarea0 + jpni 
    349          ildi(ii,ij) =  1  + nn_hls 
    350          ilei(ii,ij) = ili - nn_hls 
    351          ildj(ii,ij) =  1  + nn_hls 
    352          ilej(ii,ij) = ilj - nn_hls 
     442         iis0(ii,ij) =  1  + nn_hls 
     443         iie0(ii,ij) = ili - nn_hls 
     444         ijs0(ii,ij) =  1  + nn_hls 
     445         ije0(ii,ij) = ilj - nn_hls 
    353446 
    354447         ! East-West periodicity: change ibondi, ioea, iowe 
     
    388481      ! ---------------------------- 
    389482      ! 
    390       ! specify which subdomains are oce subdomains; other are land subdomains 
    391       ipproc(:,:) = -1 
    392       icont = -1 
    393       DO jarea = 1, jpni*jpnj 
    394          iarea0 = jarea - 1 
    395          ii = 1 + MOD(iarea0,jpni) 
    396          ij = 1 +     iarea0/jpni 
    397          IF( llisoce(ii,ij) ) THEN 
    398             icont = icont + 1 
    399             ipproc(ii,ij) = icont 
    400             iin(icont+1) = ii 
    401             ijn(icont+1) = ij 
    402          ENDIF 
    403       END DO 
    404       ! if needed add some land subdomains to reach jpnij active subdomains 
    405       i2add = jpnij - inijmin 
    406       DO jarea = 1, jpni*jpnj 
    407          iarea0 = jarea - 1 
    408          ii = 1 + MOD(iarea0,jpni) 
    409          ij = 1 +     iarea0/jpni 
    410          IF( .NOT. llisoce(ii,ij) .AND. i2add > 0 ) THEN 
    411             icont = icont + 1 
    412             ipproc(ii,ij) = icont 
    413             iin(icont+1) = ii 
    414             ijn(icont+1) = ij 
    415             i2add = i2add - 1 
    416          ENDIF 
    417       END DO 
    418       nfipproc(:,:) = ipproc(:,:) 
    419  
    420483      ! neighbour treatment: change ibondi, ibondj if next to a land zone 
    421484      DO jarea = 1, jpni*jpnj 
     
    456519         ENDIF 
    457520      END DO 
    458  
    459       ! Update il[de][ij] according to modified ibond[ij] 
    460       ! ---------------------- 
    461       DO jproc = 1, jpnij 
    462          ii = iin(jproc) 
    463          ij = ijn(jproc) 
    464          IF( ibondi(ii,ij) == -1 .OR. ibondi(ii,ij) == 2 ) ildi(ii,ij) =  1 
    465          IF( ibondi(ii,ij) ==  1 .OR. ibondi(ii,ij) == 2 ) ilei(ii,ij) = ilci(ii,ij) 
    466          IF( ibondj(ii,ij) == -1 .OR. ibondj(ii,ij) == 2 ) ildj(ii,ij) =  1 
    467          IF( ibondj(ii,ij) ==  1 .OR. ibondj(ii,ij) == 2 ) ilej(ii,ij) = ilcj(ii,ij) 
    468       END DO 
    469521       
    470522      ! 5. Subdomain print 
     
    479531            DO jj = jpnj, 1, -1 
    480532               WRITE(numout,9403) ('   ',ji=il1,il2-1) 
    481                WRITE(numout,9402) jj, (ilci(ji,jj),ilcj(ji,jj),ji=il1,il2) 
     533               WRITE(numout,9402) jj, (ijpi(ji,jj),ijpj(ji,jj),ji=il1,il2) 
    482534               WRITE(numout,9404) (ipproc(ji,jj),ji=il1,il2) 
    483535               WRITE(numout,9403) ('   ',ji=il1,il2-1) 
     
    491543 9401    FORMAT('              '   ,20('   ',i3,'          ') ) 
    492544 9402    FORMAT('       ',i3,' *  ',20(i3,'  x',i3,'   *   ') ) 
    493  9404    FORMAT('           *  '   ,20('      ',i3,'   *   ') ) 
     545 9404    FORMAT('           *  '   ,20('     ' ,i4,'   *   ') ) 
    494546      ENDIF 
    495547          
     
    536588      noea = ii_noea(narea) 
    537589      nono = ii_nono(narea) 
    538       nlci = ilci(ii,ij)   
    539       nldi = ildi(ii,ij) 
    540       nlei = ilei(ii,ij) 
    541       nlcj = ilcj(ii,ij)   
    542       nldj = ildj(ii,ij) 
    543       nlej = ilej(ii,ij) 
     590      jpi    = ijpi(ii,ij)   
     591!!$      Nis0  = iis0(ii,ij) 
     592!!$      Nie0  = iie0(ii,ij) 
     593      jpj    = ijpj(ii,ij)   
     594!!$      Njs0  = ijs0(ii,ij) 
     595!!$      Nje0  = ije0(ii,ij) 
    544596      nbondi = ibondi(ii,ij) 
    545597      nbondj = ibondj(ii,ij) 
    546598      nimpp = iimppt(ii,ij)   
    547599      njmpp = ijmppt(ii,ij) 
    548       jpi = nlci 
    549       jpj = nlcj 
    550       jpk = jpkglo                                             ! third dim 
    551 #if defined key_agrif 
    552       ! simple trick to use same vertical grid as parent but different number of levels:  
    553       ! Save maximum number of levels in jpkglo, then define all vertical grids with this number. 
    554       ! Suppress once vertical online interpolation is ok 
    555 !!$      IF(.NOT.Agrif_Root())   jpkglo = Agrif_Parent( jpkglo ) 
    556 #endif 
    557       jpim1 = jpi-1                                            ! inner domain indices 
    558       jpjm1 = jpj-1                                            !   "           " 
    559       jpkm1 = MAX( 1, jpk-1 )                                  !   "           " 
    560       jpij  = jpi*jpj                                          !  jpi x j 
     600      jpk = jpkglo                              ! third dim 
     601      ! 
     602      CALL init_doloop                          ! set start/end indices of do-loop, depending on the halo width value (nn_hls)  
     603      ! 
     604      jpim1 = jpi-1                             ! inner domain indices 
     605      jpjm1 = jpj-1                             !   "           " 
     606      jpkm1 = MAX( 1, jpk-1 )                   !   "           " 
     607      jpij  = jpi*jpj                           !  jpi x j 
    561608      DO jproc = 1, jpnij 
    562609         ii = iin(jproc) 
    563610         ij = ijn(jproc) 
    564          nlcit(jproc) = ilci(ii,ij) 
    565          nldit(jproc) = ildi(ii,ij) 
    566          nleit(jproc) = ilei(ii,ij) 
    567          nlcjt(jproc) = ilcj(ii,ij) 
    568          nldjt(jproc) = ildj(ii,ij) 
    569          nlejt(jproc) = ilej(ii,ij) 
     611         jpiall (jproc) = ijpi(ii,ij) 
     612         nis0all(jproc) = iis0(ii,ij) 
     613         nie0all(jproc) = iie0(ii,ij) 
     614         jpjall (jproc) = ijpj(ii,ij) 
     615         njs0all(jproc) = ijs0(ii,ij) 
     616         nje0all(jproc) = ije0(ii,ij) 
    570617         ibonit(jproc) = ibondi(ii,ij) 
    571618         ibonjt(jproc) = ibondj(ii,ij) 
     
    581628         WRITE(inum,'(6i8,a,3i8,a)') jpnij,jpimax,jpjmax,jpk,jpiglo,jpjglo,& 
    582629   &           ' ( local: ',narea,jpi,jpj,' )' 
    583          WRITE(inum,'(a)') 'nproc nlci nlcj nldi nldj nlei nlej nimp njmp nono noso nowe noea nbondi nbondj ' 
     630         WRITE(inum,'(a)') 'nproc   jpi  jpj Nis0 Njs0 Nie0 Nje0 nimp njmp nono noso nowe noea nbondi nbondj ' 
    584631 
    585632         DO jproc = 1, jpnij 
    586             WRITE(inum,'(13i5,2i7)')   jproc-1, nlcit  (jproc), nlcjt  (jproc),   & 
    587                &                                nldit  (jproc), nldjt  (jproc),   & 
    588                &                                nleit  (jproc), nlejt  (jproc),   & 
     633            WRITE(inum,'(13i5,2i7)')   jproc-1,  jpiall(jproc),  jpjall(jproc),   & 
     634               &                                nis0all(jproc), njs0all(jproc),   & 
     635               &                                nie0all(jproc), nje0all(jproc),   & 
    589636               &                                nimppt (jproc), njmppt (jproc),   &  
    590637               &                                ii_nono(jproc), ii_noso(jproc),   & 
     
    620667         WRITE(numout,*) '    l_Iperio = ', l_Iperio 
    621668         WRITE(numout,*) '    l_Jperio = ', l_Jperio 
    622          WRITE(numout,*) '      nlci   = ', nlci 
    623          WRITE(numout,*) '      nlcj   = ', nlcj 
    624669         WRITE(numout,*) '      nimpp  = ', nimpp 
    625670         WRITE(numout,*) '      njmpp  = ', njmpp 
    626          WRITE(numout,*) '      nreci  = ', nreci   
    627          WRITE(numout,*) '      nrecj  = ', nrecj   
    628          WRITE(numout,*) '      nn_hls = ', nn_hls  
    629671      ENDIF 
    630672 
     
    648690      ENDIF 
    649691      ! 
    650       IF( ln_nnogather ) THEN 
    651          CALL mpp_init_nfdcom     ! northfold neighbour lists 
     692      CALL init_ioipsl       ! Prepare NetCDF output file (if necessary) 
     693      !       
     694      IF (( jperio >= 3 .AND. jperio <= 6 .AND. jpni > 1 ).AND.( ln_nnogather )) THEN 
     695         CALL init_nfdcom     ! northfold neighbour lists 
    652696         IF (llwrtlay) THEN 
    653697            WRITE(inum,*) 
    654698            WRITE(inum,*) 
    655699            WRITE(inum,*) 'north fold exchanges with explicit point-to-point messaging :' 
    656             WRITE(inum,*) 'nfsloop : ', nfsloop 
    657             WRITE(inum,*) 'nfeloop : ', nfeloop 
    658700            WRITE(inum,*) 'nsndto : ', nsndto 
    659701            WRITE(inum,*) 'isendto : ', isendto 
     
    665707      DEALLOCATE(iin, ijn, ii_nono, ii_noea, ii_noso, ii_nowe,    & 
    666708         &       iimppt, ijmppt, ibondi, ibondj, ipproc, ipolj,   & 
    667          &       ilci, ilcj, ilei, ilej, ildi, ildj,              & 
     709         &       ijpi, ijpj, iie0, ije0, iis0, ijs0,              & 
    668710         &       iono, ioea, ioso, iowe, llisoce) 
    669711      ! 
     
    671713 
    672714 
    673     SUBROUTINE mpp_basic_decomposition( knbi, knbj, kimax, kjmax, kimppt, kjmppt, klci, klcj) 
    674       !!---------------------------------------------------------------------- 
    675       !!                  ***  ROUTINE mpp_basic_decomposition  *** 
     715    SUBROUTINE mpp_basesplit( kiglo, kjglo, khls, knbi, knbj, kimax, kjmax, kimppt, kjmppt, klci, klcj) 
     716      !!---------------------------------------------------------------------- 
     717      !!                  ***  ROUTINE mpp_basesplit  *** 
    676718      !!                     
    677719      !! ** Purpose :   Lay out the global domain over processors. 
     
    685727      !!                    klcj       : second dimension 
    686728      !!---------------------------------------------------------------------- 
     729      INTEGER,                                 INTENT(in   ) ::   kiglo, kjglo 
     730      INTEGER,                                 INTENT(in   ) ::   khls 
    687731      INTEGER,                                 INTENT(in   ) ::   knbi, knbj 
    688732      INTEGER,                                 INTENT(  out) ::   kimax, kjmax 
     
    691735      ! 
    692736      INTEGER ::   ji, jj 
     737      INTEGER ::   i2hls  
    693738      INTEGER ::   iresti, irestj, irm, ijpjmin 
    694       INTEGER ::   ireci, irecj 
    695       !!---------------------------------------------------------------------- 
     739      !!---------------------------------------------------------------------- 
     740      i2hls = 2*khls 
    696741      ! 
    697742#if defined key_nemocice_decomp 
    698       kimax = ( nx_global+2-2*nn_hls + (knbi-1) ) / knbi + 2*nn_hls    ! first  dim. 
    699       kjmax = ( ny_global+2-2*nn_hls + (knbj-1) ) / knbj + 2*nn_hls    ! second dim.  
     743      kimax = ( nx_global+2-i2hls + (knbi-1) ) / knbi + i2hls    ! first  dim. 
     744      kjmax = ( ny_global+2-i2hls + (knbj-1) ) / knbj + i2hls    ! second dim.  
    700745#else 
    701       kimax = ( jpiglo - 2*nn_hls + (knbi-1) ) / knbi + 2*nn_hls    ! first  dim. 
    702       kjmax = ( jpjglo - 2*nn_hls + (knbj-1) ) / knbj + 2*nn_hls    ! second dim. 
     746      kimax = ( kiglo - i2hls + (knbi-1) ) / knbi + i2hls    ! first  dim. 
     747      kjmax = ( kjglo - i2hls + (knbj-1) ) / knbj + i2hls    ! second dim. 
    703748#endif 
    704749      IF( .NOT. PRESENT(kimppt) ) RETURN 
     
    707752      ! ----------------------------------- 
    708753      !  Computation of local domain sizes klci() klcj() 
    709       !  These dimensions depend on global sizes knbi,knbj and jpiglo,jpjglo 
     754      !  These dimensions depend on global sizes knbi,knbj and kiglo,kjglo 
    710755      !  The subdomains are squares lesser than or equal to the global 
    711756      !  dimensions divided by the number of processors minus the overlap array. 
    712757      ! 
    713       ireci = 2 * nn_hls 
    714       irecj = 2 * nn_hls 
    715       iresti = 1 + MOD( jpiglo - ireci -1 , knbi ) 
    716       irestj = 1 + MOD( jpjglo - irecj -1 , knbj ) 
     758      iresti = 1 + MOD( kiglo - i2hls - 1 , knbi ) 
     759      irestj = 1 + MOD( kjglo - i2hls - 1 , knbj ) 
    717760      ! 
    718761      !  Need to use kimax and kjmax here since jpi and jpj not yet defined 
    719762#if defined key_nemocice_decomp 
    720763      ! Change padding to be consistent with CICE 
    721       klci(1:knbi-1      ,:) = kimax 
    722       klci(knbi          ,:) = jpiglo - (knbi - 1) * (kimax - nreci) 
    723       klcj(:,      1:knbj-1) = kjmax 
    724       klcj(:,          knbj) = jpjglo - (knbj - 1) * (kjmax - nrecj) 
     764      klci(1:knbi-1,:       ) = kimax 
     765      klci(  knbi  ,:       ) = kiglo - (knbi - 1) * (kimax - i2hls) 
     766      klcj(:       ,1:knbj-1) = kjmax 
     767      klcj(:       ,  knbj  ) = kjglo - (knbj - 1) * (kjmax - i2hls) 
    725768#else 
    726769      klci(1:iresti      ,:) = kimax 
    727770      klci(iresti+1:knbi ,:) = kimax-1 
    728       IF( MINVAL(klci) < 3 ) THEN 
    729          WRITE(ctmp1,*) '   mpp_basic_decomposition: minimum value of jpi must be >= 3' 
     771      IF( MINVAL(klci) < 2*i2hls ) THEN 
     772         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpi must be >= ', 2*i2hls 
    730773         WRITE(ctmp2,*) '   We have ', MINVAL(klci) 
    731774        CALL ctl_stop( 'STOP', ctmp1, ctmp2 ) 
     
    733776      IF( jperio == 3 .OR. jperio == 4 .OR. jperio == 5 .OR. jperio == 6 ) THEN 
    734777         ! minimize the size of the last row to compensate for the north pole folding coast 
    735          IF( jperio == 3 .OR. jperio == 4 )   ijpjmin = 5   ! V and F folding involves line jpj-3 that must not be south boundary 
    736          IF( jperio == 5 .OR. jperio == 6 )   ijpjmin = 4   ! V and F folding involves line jpj-2 that must not be south boundary 
    737          irm = knbj - irestj                                    ! total number of lines to be removed 
    738          klcj(:,            knbj) = MAX( ijpjmin, kjmax-irm )   ! we must have jpj >= ijpjmin in the last row 
    739          irm = irm - ( kjmax - klcj(1,knbj) )                   ! remaining number of lines to remove  
    740          irestj = knbj - 1 - irm                         
    741          klcj(:,        1:irestj) = kjmax 
     778         IF( jperio == 3 .OR. jperio == 4 )   ijpjmin = 2+3*khls   ! V and F folding must be outside of southern halos 
     779         IF( jperio == 5 .OR. jperio == 6 )   ijpjmin = 1+3*khls   ! V and F folding must be outside of southern halos 
     780         irm = knbj - irestj                                       ! total number of lines to be removed 
     781         klcj(:,knbj) = MAX( ijpjmin, kjmax-irm )                  ! we must have jpj >= ijpjmin in the last row 
     782         irm = irm - ( kjmax - klcj(1,knbj) )                      ! remaining number of lines to remove  
     783         irestj = knbj - 1 - irm 
    742784         klcj(:, irestj+1:knbj-1) = kjmax-1 
    743785      ELSE 
    744          ijpjmin = 3 
    745          klcj(:,      1:irestj) = kjmax 
    746          klcj(:, irestj+1:knbj) = kjmax-1 
    747       ENDIF 
    748       IF( MINVAL(klcj) < ijpjmin ) THEN 
    749          WRITE(ctmp1,*) '   mpp_basic_decomposition: minimum value of jpj must be >= ', ijpjmin 
     786         klcj(:, irestj+1:knbj  ) = kjmax-1 
     787      ENDIF 
     788      klcj(:,1:irestj) = kjmax 
     789      IF( MINVAL(klcj) < 2*i2hls ) THEN 
     790         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpj must be >= ', 2*i2hls 
    750791         WRITE(ctmp2,*) '   We have ', MINVAL(klcj) 
    751792         CALL ctl_stop( 'STOP', ctmp1, ctmp2 ) 
     
    761802         DO jj = 1, knbj 
    762803            DO ji = 2, knbi 
    763                kimppt(ji,jj) = kimppt(ji-1,jj) + klci(ji-1,jj) - ireci 
     804               kimppt(ji,jj) = kimppt(ji-1,jj) + klci(ji-1,jj) - i2hls 
    764805            END DO 
    765806         END DO 
     
    769810         DO jj = 2, knbj 
    770811            DO ji = 1, knbi 
    771                kjmppt(ji,jj) = kjmppt(ji,jj-1) + klcj(ji,jj-1) - irecj 
     812               kjmppt(ji,jj) = kjmppt(ji,jj-1) + klcj(ji,jj-1) - i2hls 
    772813            END DO 
    773814         END DO 
    774815      ENDIF 
    775816       
    776    END SUBROUTINE mpp_basic_decomposition 
    777  
    778  
    779    SUBROUTINE mpp_init_bestpartition( knbij, knbi, knbj, knbcnt, ldlist ) 
    780       !!---------------------------------------------------------------------- 
    781       !!                 ***  ROUTINE mpp_init_bestpartition  *** 
     817   END SUBROUTINE mpp_basesplit 
     818 
     819 
     820   SUBROUTINE bestpartition( knbij, knbi, knbj, knbcnt, ldlist ) 
     821      !!---------------------------------------------------------------------- 
     822      !!                 ***  ROUTINE bestpartition  *** 
    782823      !! 
    783824      !! ** Purpose : 
     
    794835      INTEGER :: isziref, iszjref 
    795836      INTEGER :: inbij, iszij 
    796       INTEGER :: inbimax, inbjmax, inbijmax 
     837      INTEGER :: inbimax, inbjmax, inbijmax, inbijold 
    797838      INTEGER :: isz0, isz1 
    798839      INTEGER, DIMENSION(  :), ALLOCATABLE :: indexok 
     
    821862      inbimax = 0 
    822863      inbjmax = 0 
    823       isziref = jpiglo*jpjglo+1 
    824       iszjref = jpiglo*jpjglo+1 
     864      isziref = Ni0glo*Nj0glo+1 
     865      iszjref = Ni0glo*Nj0glo+1 
    825866      ! 
    826867      ! get the list of knbi that gives a smaller jpimax than knbi-1 
     
    830871         iszitst = ( nx_global+2-2*nn_hls + (ji-1) ) / ji + 2*nn_hls    ! first  dim. 
    831872#else 
    832          iszitst = ( jpiglo - 2*nn_hls + (ji-1) ) / ji + 2*nn_hls 
     873         iszitst = ( Ni0glo + (ji-1) ) / ji 
    833874#endif 
    834875         IF( iszitst < isziref ) THEN 
     
    841882         iszjtst = ( ny_global+2-2*nn_hls + (ji-1) ) / ji + 2*nn_hls    ! first  dim. 
    842883#else 
    843          iszjtst = ( jpjglo - 2*nn_hls + (ji-1) ) / ji + 2*nn_hls 
     884         iszjtst = ( Nj0glo + (ji-1) ) / ji 
    844885#endif 
    845886         IF( iszjtst < iszjref ) THEN 
     
    881922      iszij1(:) = iszi1(:) * iszj1(:) 
    882923 
    883       ! if therr is no land and no print 
    884       IF( .NOT. llist .AND. numbot == -1 ) THEN 
     924      ! if there is no land and no print 
     925      IF( .NOT. llist .AND. numbot == -1 .AND. numbdy == -1 ) THEN 
    885926         ! get the smaller partition which gives the smallest subdomain size 
    886927         ii = MINLOC(inbij1, mask = iszij1 == MINVAL(iszij1), dim = 1) 
     
    896937      isz0 = 0                                                  ! number of best partitions      
    897938      inbij = 1                                                 ! start with the min value of inbij1 => 1 
    898       iszij = jpiglo*jpjglo+1                                   ! default: larger than global domain 
     939      iszij = Ni0glo*Nj0glo+1                                   ! default: larger than global domain 
    899940      DO WHILE( inbij <= inbijmax )                             ! if we did not reach the max of inbij1 
    900941         ii = MINLOC(iszij1, mask = inbij1 == inbij, dim = 1)   ! warning: send back the first occurence if multiple results 
     
    919960      DEALLOCATE( indexok, inbi1, inbj1, iszi1, iszj1 ) 
    920961 
    921       IF( llist ) THEN  ! we print about 21 best partitions 
     962      IF( llist ) THEN 
    922963         IF(lwp) THEN 
    923964            WRITE(numout,*) 
    924             WRITE(numout,         *) '                  For your information:' 
    925             WRITE(numout,'(a,i5,a)') '  list of the best partitions around ',   knbij, ' mpi processes' 
    926             WRITE(numout,         *) '  --------------------------------------', '-----', '--------------' 
     965            WRITE(numout,*) '                  For your information:' 
     966            WRITE(numout,*) '  list of the best partitions including land supression' 
     967            WRITE(numout,*) '  -----------------------------------------------------' 
    927968            WRITE(numout,*) 
    928969         END IF 
    929          iitarget = MINLOC( inbi0(:)*inbj0(:), mask = inbi0(:)*inbj0(:) >= knbij, dim = 1 ) 
    930          DO ji = MAX(1,iitarget-10), MIN(isz0,iitarget+10) 
     970         ji = isz0   ! initialization with the largest value 
     971         ALLOCATE( llisoce(inbi0(ji), inbj0(ji)) ) 
     972         CALL mpp_is_ocean( llisoce )   ! Warning: must be call by all cores (call mpp_sum) 
     973         inbijold = COUNT(llisoce) 
     974         DEALLOCATE( llisoce ) 
     975         DO ji =isz0-1,1,-1 
    931976            ALLOCATE( llisoce(inbi0(ji), inbj0(ji)) ) 
    932             CALL mpp_init_isoce( inbi0(ji), inbj0(ji), llisoce ) ! Warning: must be call by all cores (call mpp_sum) 
     977            CALL mpp_is_ocean( llisoce )  ! Warning: must be call by all cores (call mpp_sum) 
    933978            inbij = COUNT(llisoce) 
    934979            DEALLOCATE( llisoce ) 
    935             IF(lwp) WRITE(numout,'(a, i5, a, i5, a, i4, a, i4, a, i9, a, i5, a, i5, a)')    & 
    936                &     'nb_cores ' , inbij,' oce + ', inbi0(ji)*inbj0(ji) - inbij             & 
    937                &                                , ' land ( ', inbi0(ji),' x ', inbj0(ji),   & 
    938                & ' ), nb_points ', iszi0(ji)*iszj0(ji),' ( ', iszi0(ji),' x ', iszj0(ji),' )' 
     980            IF(lwp .AND. inbij < inbijold) THEN 
     981               WRITE(numout,'(a, i6, a, i6, a, f4.1, a, i9, a, i6, a, i6, a)')                                 & 
     982                  &   'nb_cores oce: ', inbij, ', land domains excluded: ', inbi0(ji)*inbj0(ji) - inbij,       & 
     983                  &   ' (', REAL(inbi0(ji)*inbj0(ji) - inbij,wp) / REAL(inbi0(ji)*inbj0(ji),wp) *100.,         & 
     984                  &   '%), largest oce domain: ', iszi0(ji)*iszj0(ji), ' ( ', iszi0(ji),' x ', iszj0(ji), ' )' 
     985               inbijold = inbij 
     986            END IF 
    939987         END DO 
    940988         DEALLOCATE( inbi0, inbj0, iszi0, iszj0 ) 
    941          RETURN 
     989         IF(lwp) THEN 
     990            WRITE(numout,*) 
     991            WRITE(numout,*)  '  -----------------------------------------------------------' 
     992         ENDIF 
     993         CALL mppsync 
     994         CALL mppstop( ld_abort = .TRUE. ) 
    942995      ENDIF 
    943996       
     
    9481001         ii = ii -1  
    9491002         ALLOCATE( llisoce(inbi0(ii), inbj0(ii)) ) 
    950          CALL mpp_init_isoce( inbi0(ii), inbj0(ii), llisoce )            ! must be done by all core 
     1003         CALL mpp_is_ocean( llisoce )            ! must be done by all core 
    9511004         inbij = COUNT(llisoce) 
    9521005         DEALLOCATE( llisoce ) 
     
    9571010      DEALLOCATE( inbi0, inbj0 ) 
    9581011      ! 
    959    END SUBROUTINE mpp_init_bestpartition 
     1012   END SUBROUTINE bestpartition 
    9601013    
    9611014    
     
    9661019      !! ** Purpose : the the proportion of land points in the surface land-sea mask 
    9671020      !! 
    968       !! ** Method  : read iproc strips (of length jpiglo) of the land-sea mask 
     1021      !! ** Method  : read iproc strips (of length Ni0glo) of the land-sea mask 
    9691022      !!---------------------------------------------------------------------- 
    9701023      REAL(wp), INTENT(  out) :: propland    ! proportion of land points in the global domain (between 0 and 1) 
     
    9771030      !!---------------------------------------------------------------------- 
    9781031      ! do nothing if there is no land-sea mask 
    979       IF( numbot == -1 ) THEN 
     1032      IF( numbot == -1 .and. numbdy == -1 ) THEN 
    9801033         propland = 0. 
    9811034         RETURN 
     
    9831036 
    9841037      ! number of processes reading the bathymetry file  
    985       iproc = MINVAL( (/mppsize, jpjglo/2, 100/) )  ! read a least 2 lines, no more that 100 processes reading at the same time 
     1038      iproc = MINVAL( (/mppsize, Nj0glo/2, 100/) )  ! read a least 2 lines, no more that 100 processes reading at the same time 
    9861039       
    9871040      ! we want to read iproc strips of the land-sea mask. -> pick up iproc processes every idiv processes starting at 1 
     
    9931046      IF( MOD( narea-1, idiv ) == 0 .AND. iarea < iproc ) THEN   ! beware idiv can be = to 1 
    9941047         ! 
    995          ijsz = jpjglo / iproc                                               ! width of the stripe to read 
    996          IF( iarea < MOD(jpjglo,iproc) ) ijsz = ijsz + 1 
    997          ijstr = iarea*(jpjglo/iproc) + MIN(iarea, MOD(jpjglo,iproc)) + 1    ! starting j position of the reading 
    998          ! 
    999          ALLOCATE( lloce(jpiglo, ijsz) )                                     ! allocate the strip 
    1000          CALL mpp_init_readbot_strip( ijstr, ijsz, lloce ) 
     1048         ijsz = Nj0glo / iproc                                               ! width of the stripe to read 
     1049         IF( iarea < MOD(Nj0glo,iproc) ) ijsz = ijsz + 1 
     1050         ijstr = iarea*(Nj0glo/iproc) + MIN(iarea, MOD(Nj0glo,iproc)) + 1    ! starting j position of the reading 
     1051         ! 
     1052         ALLOCATE( lloce(Ni0glo, ijsz) )                                     ! allocate the strip 
     1053         CALL readbot_strip( ijstr, ijsz, lloce ) 
    10011054         inboce = COUNT(lloce)                                               ! number of ocean point in the stripe 
    10021055         DEALLOCATE(lloce) 
     
    10071060      CALL mpp_sum( 'mppini', inboce )   ! total number of ocean points over the global domain 
    10081061      ! 
    1009       propland = REAL( jpiglo*jpjglo - inboce, wp ) / REAL( jpiglo*jpjglo, wp )  
     1062      propland = REAL( Ni0glo*Nj0glo - inboce, wp ) / REAL( Ni0glo*Nj0glo, wp )  
    10101063      ! 
    10111064   END SUBROUTINE mpp_init_landprop 
    10121065    
    10131066    
    1014    SUBROUTINE mpp_init_isoce( knbi, knbj, ldisoce ) 
    1015       !!---------------------------------------------------------------------- 
    1016       !!                  ***  ROUTINE mpp_init_nboce  *** 
    1017       !! 
    1018       !! ** Purpose : check for a mpi domain decomposition knbi x knbj which 
    1019       !!              subdomains contain at least 1 ocean point 
    1020       !! 
    1021       !! ** Method  : read knbj strips (of length jpiglo) of the land-sea mask 
    1022       !!---------------------------------------------------------------------- 
    1023       INTEGER,                       INTENT(in   ) ::   knbi, knbj     ! domain decomposition 
    1024       LOGICAL, DIMENSION(knbi,knbj), INTENT(  out) ::   ldisoce        ! .true. if a sub domain constains 1 ocean point  
    1025       ! 
    1026       INTEGER, DIMENSION(knbi,knbj) ::   inboce                        ! number oce oce pint in each mpi subdomain 
    1027       INTEGER, DIMENSION(knbi*knbj) ::   inboce_1d 
     1067   SUBROUTINE mpp_is_ocean( ldisoce ) 
     1068      !!---------------------------------------------------------------------- 
     1069      !!                  ***  ROUTINE mpp_is_ocean  *** 
     1070      !! 
     1071      !! ** Purpose : Check for a mpi domain decomposition inbi x inbj which 
     1072      !!              subdomains, including 1 halo (even if nn_hls>1), contain 
     1073      !!              at least 1 ocean point. 
     1074      !!              We must indeed ensure that each subdomain that is a neighbour 
     1075      !!              of a land subdomain as only land points on its boundary 
     1076      !!              (inside the inner subdomain) with the land subdomain. 
     1077      !!              This is needed to get the proper bondary conditions on 
     1078      !!              a subdomain with a closed boundary. 
     1079      !! 
     1080      !! ** Method  : read inbj strips (of length Ni0glo) of the land-sea mask 
     1081      !!---------------------------------------------------------------------- 
     1082      LOGICAL, DIMENSION(:,:), INTENT(  out) ::   ldisoce        ! .true. if a sub domain constains 1 ocean point  
     1083      ! 
    10281084      INTEGER :: idiv, iimax, ijmax, iarea 
     1085      INTEGER :: inbi, inbj, inx, iny, inry, isty 
    10291086      INTEGER :: ji, jn 
    1030       LOGICAL, ALLOCATABLE, DIMENSION(:,:) ::   lloce                  ! lloce(i,j) = .true. if the point (i,j) is ocean  
    1031       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ilci 
    1032       INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ilcj 
     1087      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   inboce           ! number oce oce pint in each mpi subdomain 
     1088      INTEGER, ALLOCATABLE, DIMENSION(:  ) ::   inboce_1d 
     1089      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   iimppt, ijpi 
     1090      INTEGER, ALLOCATABLE, DIMENSION(:,:) ::   ijmppt, ijpj 
     1091      LOGICAL, ALLOCATABLE, DIMENSION(:,:) ::   lloce            ! lloce(i,j) = .true. if the point (i,j) is ocean  
    10331092      !!---------------------------------------------------------------------- 
    10341093      ! do nothing if there is no land-sea mask 
    1035       IF( numbot == -1 ) THEN 
     1094      IF( numbot == -1 .AND. numbdy == -1 ) THEN 
    10361095         ldisoce(:,:) = .TRUE. 
    10371096         RETURN 
    10381097      ENDIF 
    1039  
    1040       ! we want to read knbj strips of the land-sea mask. -> pick up knbj processes every idiv processes starting at 1 
    1041       IF           ( knbj == 1 ) THEN   ;   idiv = mppsize 
    1042       ELSE IF ( mppsize < knbj ) THEN   ;   idiv = 1 
    1043       ELSE                              ;   idiv = ( mppsize - 1 ) / ( knbj - 1 ) 
    1044       ENDIF 
     1098      ! 
     1099      inbi = SIZE( ldisoce, dim = 1 ) 
     1100      inbj = SIZE( ldisoce, dim = 2 ) 
     1101      ! 
     1102      ! we want to read inbj strips of the land-sea mask. -> pick up inbj processes every idiv processes starting at 1 
     1103      IF           ( inbj == 1 ) THEN   ;   idiv = mppsize 
     1104      ELSE IF ( mppsize < inbj ) THEN   ;   idiv = 1 
     1105      ELSE                              ;   idiv = ( mppsize - 1 ) / ( inbj - 1 ) 
     1106      ENDIF 
     1107      ! 
     1108      ALLOCATE( inboce(inbi,inbj), inboce_1d(inbi*inbj) ) 
    10451109      inboce(:,:) = 0          ! default no ocean point found 
    1046  
    1047       DO jn = 0, (knbj-1)/mppsize   ! if mppsize < knbj : more strips than mpi processes (because of potential land domains) 
    1048          ! 
    1049          iarea = (narea-1)/idiv + jn * mppsize   ! involed process number (starting counting at 0) 
    1050          IF( MOD( narea-1, idiv ) == 0 .AND. iarea < knbj ) THEN   ! beware idiv can be = to 1 
     1110      ! 
     1111      DO jn = 0, (inbj-1)/mppsize   ! if mppsize < inbj : more strips than mpi processes (because of potential land domains) 
     1112         ! 
     1113         iarea = (narea-1)/idiv + jn * mppsize + 1                     ! involed process number (starting counting at 1) 
     1114         IF( MOD( narea-1, idiv ) == 0 .AND. iarea <= inbj ) THEN      ! beware idiv can be = to 1 
    10511115            ! 
    1052             ALLOCATE( iimppt(knbi,knbj), ijmppt(knbi,knbj), ilci(knbi,knbj), ilcj(knbi,knbj) ) 
    1053             CALL mpp_basic_decomposition( knbi, knbj, iimax, ijmax, iimppt, ijmppt, ilci, ilcj ) 
     1116            ALLOCATE( iimppt(inbi,inbj), ijmppt(inbi,inbj), ijpi(inbi,inbj), ijpj(inbi,inbj) ) 
     1117            CALL mpp_basesplit( Ni0glo, Nj0glo, 0, inbi, inbj, iimax, ijmax, iimppt, ijmppt, ijpi, ijpj ) 
    10541118            ! 
    1055             ALLOCATE( lloce(jpiglo, ilcj(1,iarea+1)) )                                         ! allocate the strip 
    1056             CALL mpp_init_readbot_strip( ijmppt(1,iarea+1), ilcj(1,iarea+1), lloce )           ! read the strip 
    1057             DO  ji = 1, knbi 
    1058                inboce(ji,iarea+1) = COUNT( lloce(iimppt(ji,1):iimppt(ji,1)+ilci(ji,1)-1,:) )   ! number of ocean point in subdomain 
     1119            inx = Ni0glo + 2   ;   iny = ijpj(1,iarea) + 2             ! strip size + 1 halo on each direction (even if nn_hls>1) 
     1120            ALLOCATE( lloce(inx, iny) )                                ! allocate the strip 
     1121            inry = iny - COUNT( (/ iarea == 1, iarea == inbj /) )      ! number of point to read in y-direction 
     1122            isty = 1 + COUNT( (/ iarea == 1 /) )                       ! read from the first or the second line? 
     1123            CALL readbot_strip( ijmppt(1,iarea) - 2 + isty, inry, lloce(2:inx-1, isty:inry+isty-1) )   ! read the strip 
     1124            !  
     1125            IF( iarea == 1    ) THEN                                   ! the first line was not read 
     1126               IF( jperio == 2 .OR. jperio == 7 ) THEN                 !   north-south periodocity 
     1127                  CALL readbot_strip( Nj0glo, 1, lloce(2:inx-1, 1) )   !   read the last line -> first line of lloce 
     1128               ELSE 
     1129                  lloce(2:inx-1,  1) = .FALSE.                         !   closed boundary 
     1130               ENDIF 
     1131            ENDIF 
     1132            IF( iarea == inbj ) THEN                                   ! the last line was not read 
     1133               IF( jperio == 2 .OR. jperio == 7 ) THEN                 !   north-south periodocity 
     1134                  CALL readbot_strip( 1, 1, lloce(2:inx-1,iny) )       !      read the first line -> last line of lloce 
     1135               ELSEIF( jperio == 3 .OR. jperio == 4 ) THEN             !   north-pole folding T-pivot, T-point  
     1136                  lloce(2,iny) = lloce(2,iny-2)                        !      here we have 1 halo (even if nn_hls>1) 
     1137                  DO ji = 3,inx-1 
     1138                     lloce(ji,iny  ) = lloce(inx-ji+2,iny-2)           !      ok, we have at least 3 lines 
     1139                  END DO 
     1140                  DO ji = inx/2+2,inx-1 
     1141                     lloce(ji,iny-1) = lloce(inx-ji+2,iny-1) 
     1142                  END DO 
     1143               ELSEIF( jperio == 5 .OR. jperio == 6 ) THEN             !   north-pole folding F-pivot, T-point, 1 halo 
     1144                  lloce(inx/2+1,iny-1) = lloce(inx/2,iny-1)            !      here we have 1 halo (even if nn_hls>1) 
     1145                  lloce(inx  -1,iny-1) = lloce(2    ,iny-1) 
     1146                  DO ji = 2,inx-1 
     1147                     lloce(ji,iny) = lloce(inx-ji+1,iny-1) 
     1148                  END DO 
     1149               ELSE                                                    !   closed boundary 
     1150                  lloce(2:inx-1,iny) = .FALSE. 
     1151               ENDIF 
     1152            ENDIF 
     1153            !                                                          ! first and last column were not read 
     1154            IF( jperio == 1 .OR. jperio == 4 .OR. jperio == 6 .OR. jperio == 7 ) THEN 
     1155               lloce(1,:) = lloce(inx-1,:)   ;   lloce(inx,:) = lloce(2,:)   ! east-west periodocity 
     1156            ELSE 
     1157               lloce(1,:) = .FALSE.          ;   lloce(inx,:) = .FALSE.      ! closed boundary 
     1158            ENDIF 
     1159            ! 
     1160            DO  ji = 1, inbi 
     1161               inboce(ji,iarea) = COUNT( lloce(iimppt(ji,1):iimppt(ji,1)+ijpi(ji,1)+1,:) )   ! lloce as 2 points more than Ni0glo 
    10591162            END DO 
    10601163            ! 
    10611164            DEALLOCATE(lloce) 
    1062             DEALLOCATE(iimppt, ijmppt, ilci, ilcj) 
     1165            DEALLOCATE(iimppt, ijmppt, ijpi, ijpj) 
    10631166            ! 
    10641167         ENDIF 
    10651168      END DO 
    10661169    
    1067       inboce_1d = RESHAPE(inboce, (/ knbi*knbj /)) 
     1170      inboce_1d = RESHAPE(inboce, (/ inbi*inbj /)) 
    10681171      CALL mpp_sum( 'mppini', inboce_1d ) 
    1069       inboce = RESHAPE(inboce_1d, (/knbi, knbj/)) 
     1172      inboce = RESHAPE(inboce_1d, (/inbi, inbj/)) 
    10701173      ldisoce(:,:) = inboce(:,:) /= 0 
    1071       ! 
    1072    END SUBROUTINE mpp_init_isoce 
     1174      DEALLOCATE(inboce, inboce_1d) 
     1175      ! 
     1176   END SUBROUTINE mpp_is_ocean 
    10731177    
    10741178    
    1075    SUBROUTINE mpp_init_readbot_strip( kjstr, kjcnt, ldoce ) 
    1076       !!---------------------------------------------------------------------- 
    1077       !!                  ***  ROUTINE mpp_init_readbot_strip  *** 
     1179   SUBROUTINE readbot_strip( kjstr, kjcnt, ldoce ) 
     1180      !!---------------------------------------------------------------------- 
     1181      !!                  ***  ROUTINE readbot_strip  *** 
    10781182      !! 
    10791183      !! ** Purpose : Read relevant bathymetric information in order to 
     
    10811185      !!              of land domains, in an mpp computation. 
    10821186      !! 
    1083       !! ** Method  : read stipe of size (jpiglo,...) 
    1084       !!---------------------------------------------------------------------- 
    1085       INTEGER                         , INTENT(in   ) :: kjstr       ! starting j position of the reading 
    1086       INTEGER                         , INTENT(in   ) :: kjcnt       ! number of lines to read 
    1087       LOGICAL, DIMENSION(jpiglo,kjcnt), INTENT(  out) :: ldoce       ! ldoce(i,j) = .true. if the point (i,j) is ocean  
     1187      !! ** Method  : read stipe of size (Ni0glo,...) 
     1188      !!---------------------------------------------------------------------- 
     1189      INTEGER                         , INTENT(in   ) ::   kjstr       ! starting j position of the reading 
     1190      INTEGER                         , INTENT(in   ) ::   kjcnt       ! number of lines to read 
     1191      LOGICAL, DIMENSION(Ni0glo,kjcnt), INTENT(  out) ::  ldoce       ! ldoce(i,j) = .true. if the point (i,j) is ocean  
    10881192      ! 
    10891193      INTEGER                           ::   inumsave                ! local logical unit 
    1090       REAL(wp), DIMENSION(jpiglo,kjcnt) ::   zbot 
     1194      REAL(wp), DIMENSION(Ni0glo,kjcnt) ::   zbot, zbdy  
    10911195      !!---------------------------------------------------------------------- 
    10921196      ! 
    10931197      inumsave = numout   ;   numout = numnul   !   redirect all print to /dev/null 
    10941198      ! 
    1095       IF( numbot /= -1 ) THEN 
    1096          CALL iom_get( numbot, jpdom_unknown, 'bottom_level', zbot, kstart = (/1,kjstr/), kcount = (/jpiglo, kjcnt/) ) 
     1199      IF( numbot /= -1 ) THEN    
     1200         CALL iom_get( numbot, jpdom_unknown, 'bottom_level', zbot, kstart = (/1,kjstr/), kcount = (/Ni0glo, kjcnt/) ) 
    10971201      ELSE 
    1098          zbot(:,:) = 1.                         ! put a non-null value 
    1099       ENDIF 
    1100  
    1101       ! 
    1102       ldoce(:,:) = zbot(:,:) > 0. 
     1202         zbot(:,:) = 1._wp                      ! put a non-null value 
     1203      ENDIF 
     1204      ! 
     1205      IF( numbdy /= -1 ) THEN                   ! Adjust with bdy_msk if it exists     
     1206         CALL iom_get ( numbdy, jpdom_unknown,     'bdy_msk', zbdy, kstart = (/1,kjstr/), kcount = (/Ni0glo, kjcnt/) ) 
     1207         zbot(:,:) = zbot(:,:) * zbdy(:,:) 
     1208      ENDIF 
     1209      ! 
     1210      ldoce(:,:) = zbot(:,:) > 0._wp 
    11031211      numout = inumsave 
    11041212      ! 
    1105    END SUBROUTINE mpp_init_readbot_strip 
    1106  
    1107    SUBROUTINE mpp_init_nfdcom 
    1108       !!---------------------------------------------------------------------- 
    1109       !!                     ***  ROUTINE  mpp_init_nfdcom  *** 
     1213   END SUBROUTINE readbot_strip 
     1214 
     1215 
     1216   SUBROUTINE mpp_getnum( ldisoce, kproc, kipos, kjpos ) 
     1217      !!---------------------------------------------------------------------- 
     1218      !!                  ***  ROUTINE mpp_getnum  *** 
     1219      !! 
     1220      !! ** Purpose : give a number to each MPI subdomains (starting at 0) 
     1221      !! 
     1222      !! ** Method  : start from bottom left. First skip land subdomain, and finally use them if needed 
     1223      !!---------------------------------------------------------------------- 
     1224      LOGICAL, DIMENSION(:,:), INTENT(in   ) ::   ldisoce     ! F if land process 
     1225      INTEGER, DIMENSION(:,:), INTENT(  out) ::   kproc       ! subdomain number (-1 if supressed, starting at 0) 
     1226      INTEGER, DIMENSION(  :), INTENT(  out) ::   kipos       ! i-position of the subdomain (from 1 to jpni) 
     1227      INTEGER, DIMENSION(  :), INTENT(  out) ::   kjpos       ! j-position of the subdomain (from 1 to jpnj) 
     1228      ! 
     1229      INTEGER :: ii, ij, jarea, iarea0 
     1230      INTEGER :: icont, i2add , ini, inj, inij 
     1231      !!---------------------------------------------------------------------- 
     1232      ! 
     1233      ini = SIZE(ldisoce, dim = 1) 
     1234      inj = SIZE(ldisoce, dim = 2) 
     1235      inij = SIZE(kipos) 
     1236      ! 
     1237      ! specify which subdomains are oce subdomains; other are land subdomains 
     1238      kproc(:,:) = -1 
     1239      icont = -1 
     1240      DO jarea = 1, ini*inj 
     1241         iarea0 = jarea - 1 
     1242         ii = 1 + MOD(iarea0,ini) 
     1243         ij = 1 +     iarea0/ini 
     1244         IF( ldisoce(ii,ij) ) THEN 
     1245            icont = icont + 1 
     1246            kproc(ii,ij) = icont 
     1247            kipos(icont+1) = ii 
     1248            kjpos(icont+1) = ij 
     1249         ENDIF 
     1250      END DO 
     1251      ! if needed add some land subdomains to reach inij active subdomains 
     1252      i2add = inij - COUNT( ldisoce ) 
     1253      DO jarea = 1, ini*inj 
     1254         iarea0 = jarea - 1 
     1255         ii = 1 + MOD(iarea0,ini) 
     1256         ij = 1 +     iarea0/ini 
     1257         IF( .NOT. ldisoce(ii,ij) .AND. i2add > 0 ) THEN 
     1258            icont = icont + 1 
     1259            kproc(ii,ij) = icont 
     1260            kipos(icont+1) = ii 
     1261            kjpos(icont+1) = ij 
     1262            i2add = i2add - 1 
     1263         ENDIF 
     1264      END DO 
     1265      ! 
     1266   END SUBROUTINE mpp_getnum 
     1267 
     1268 
     1269   SUBROUTINE init_ioipsl 
     1270      !!---------------------------------------------------------------------- 
     1271      !!                  ***  ROUTINE init_ioipsl  *** 
     1272      !! 
     1273      !! ** Purpose :    
     1274      !! 
     1275      !! ** Method  :    
     1276      !! 
     1277      !! History : 
     1278      !!   9.0  !  04-03  (G. Madec )  MPP-IOIPSL  
     1279      !!   " "  !  08-12  (A. Coward)  addition in case of jpni*jpnj < jpnij 
     1280      !!---------------------------------------------------------------------- 
     1281      INTEGER, DIMENSION(2) ::   iglo, iloc, iabsf, iabsl, ihals, ihale, idid 
     1282      !!---------------------------------------------------------------------- 
     1283 
     1284      ! The domain is split only horizontally along i- or/and j- direction 
     1285      ! So we need at the most only 1D arrays with 2 elements. 
     1286      ! Set idompar values equivalent to the jpdom_local_noextra definition 
     1287      ! used in IOM. This works even if jpnij .ne. jpni*jpnj. 
     1288      iglo( :) = (/ Ni0glo, Nj0glo /) 
     1289      iloc( :) = (/ Ni_0  , Nj_0   /) 
     1290      iabsf(:) = (/ Nis0  , Njs0   /) + (/ nimpp, njmpp /) - 1 - nn_hls   ! corresponds to mig0(Nis0) but mig0 is not yet defined! 
     1291      iabsl(:) = iabsf(:) + iloc(:) - 1 
     1292      ihals(:) = (/ 0     , 0      /) 
     1293      ihale(:) = (/ 0     , 0      /) 
     1294      idid( :) = (/ 1     , 2      /) 
     1295 
     1296      IF(lwp) THEN 
     1297          WRITE(numout,*) 
     1298          WRITE(numout,*) 'mpp init_ioipsl :   iloc  = ', iloc 
     1299          WRITE(numout,*) '~~~~~~~~~~~~~~~     iabsf = ', iabsf 
     1300          WRITE(numout,*) '                    ihals = ', ihals 
     1301          WRITE(numout,*) '                    ihale = ', ihale 
     1302      ENDIF 
     1303      ! 
     1304      CALL flio_dom_set ( jpnij, nproc, idid, iglo, iloc, iabsf, iabsl, ihals, ihale, 'BOX', nidom) 
     1305      ! 
     1306   END SUBROUTINE init_ioipsl   
     1307 
     1308 
     1309   SUBROUTINE init_nfdcom 
     1310      !!---------------------------------------------------------------------- 
     1311      !!                     ***  ROUTINE  init_nfdcom  *** 
    11101312      !! ** Purpose :   Setup for north fold exchanges with explicit  
    11111313      !!                point-to-point messaging 
     
    11171319      !!---------------------------------------------------------------------- 
    11181320      INTEGER  ::   sxM, dxM, sxT, dxT, jn 
    1119       INTEGER  ::   njmppmax 
    1120       !!---------------------------------------------------------------------- 
    1121       ! 
    1122       njmppmax = MAXVAL( njmppt ) 
     1321      !!---------------------------------------------------------------------- 
    11231322      ! 
    11241323      !initializes the north-fold communication variables 
     
    11261325      nsndto     = 0 
    11271326      ! 
    1128       IF ( njmpp == njmppmax ) THEN      ! if I am a process in the north 
     1327      IF ( njmpp == MAXVAL( njmppt ) ) THEN      ! if I am a process in the north 
    11291328         ! 
    11301329         !sxM is the first point (in the global domain) needed to compute the north-fold for the current process 
    1131          sxM = jpiglo - nimppt(narea) - nlcit(narea) + 1 
     1330         sxM = jpiglo - nimppt(narea) - jpiall(narea) + 1 
    11321331         !dxM is the last point (in the global domain) needed to compute the north-fold for the current process 
    11331332         dxM = jpiglo - nimppt(narea) + 2 
     
    11381337         DO jn = 1, jpni 
    11391338            ! 
    1140             sxT = nfiimpp(jn, jpnj)                            ! sxT = 1st  point (in the global domain) of the jn process 
    1141             dxT = nfiimpp(jn, jpnj) + nfilcit(jn, jpnj) - 1    ! dxT = last point (in the global domain) of the jn process 
     1339            sxT = nfimpp(jn)                    ! sxT = 1st  point (in the global domain) of the jn process 
     1340            dxT = nfimpp(jn) + nfjpi(jn) - 1    ! dxT = last point (in the global domain) of the jn process 
    11421341            ! 
    11431342            IF    ( sxT < sxM  .AND.  sxM < dxT ) THEN 
     
    11531352            ! 
    11541353         END DO 
    1155          nfsloop = 1 
    1156          nfeloop = nlci 
    1157          DO jn = 2,jpni-1 
    1158             IF( nfipproc(jn,jpnj) == (narea - 1) ) THEN 
    1159                IF( nfipproc(jn-1,jpnj) == -1 )   nfsloop = nldi 
    1160                IF( nfipproc(jn+1,jpnj) == -1 )   nfeloop = nlei 
    1161             ENDIF 
    1162          END DO 
    11631354         ! 
    11641355      ENDIF 
    11651356      l_north_nogather = .TRUE. 
    11661357      ! 
    1167    END SUBROUTINE mpp_init_nfdcom 
    1168  
     1358   END SUBROUTINE init_nfdcom 
    11691359 
    11701360#endif 
    11711361 
     1362   SUBROUTINE init_doloop 
     1363      !!---------------------------------------------------------------------- 
     1364      !!                  ***  ROUTINE init_doloop  *** 
     1365      !! 
     1366      !! ** Purpose :   set the starting/ending indices of DO-loop 
     1367      !!              These indices are used in do_loop_substitute.h90 
     1368      !!---------------------------------------------------------------------- 
     1369      ! 
     1370      Nis0 =   1+nn_hls   ;   Nis1 = Nis0-1   ;   Nis2 = MAX(  1, Nis0-2) 
     1371      Njs0 =   1+nn_hls   ;   Njs1 = Njs0-1   ;   Njs2 = MAX(  1, Njs0-2)   
     1372      !                                                  
     1373      Nie0 = jpi-nn_hls   ;   Nie1 = Nie0+1   ;   Nie2 = MIN(jpi, Nie0+2) 
     1374      Nje0 = jpj-nn_hls   ;   Nje1 = Nje0+1   ;   Nje2 = MIN(jpj, Nje0+2) 
     1375      ! 
     1376      IF( nn_hls == 1 ) THEN          !* halo size of 1 
     1377         ! 
     1378         Nis1nxt2 = Nis0   ;   Njs1nxt2 = Njs0 
     1379         Nie1nxt2 = Nie0   ;   Nje1nxt2 = Nje0 
     1380         ! 
     1381      ELSE                            !* larger halo size...  
     1382         ! 
     1383         Nis1nxt2 = Nis1   ;   Njs1nxt2 = Njs1 
     1384         Nie1nxt2 = Nie1   ;   Nje1nxt2 = Nje1 
     1385         ! 
     1386      ENDIF 
     1387      ! 
     1388      Ni_0 = Nie0 - Nis0 + 1 
     1389      Nj_0 = Nje0 - Njs0 + 1 
     1390      Ni_1 = Nie1 - Nis1 + 1 
     1391      Nj_1 = Nje1 - Njs1 + 1 
     1392      Ni_2 = Nie2 - Nis2 + 1 
     1393      Nj_2 = Nje2 - Njs2 + 1 
     1394      ! 
     1395   END SUBROUTINE init_doloop 
     1396    
    11721397   !!====================================================================== 
    11731398END MODULE mppini 
  • utils/tools/DOMAINcfg/src/nc4interface.f90

    r6951 r14623  
    55! See IOIPSL/IOIPSL_License_CeCILL.txt 
    66!--------------------------------------------------------------------- 
    7  
     7#if ! defined key_netcdf4 
    88      !!-------------------------------------------------------------------- 
    99      !! NOT 'key_netcdf4' Defines dummy routines for netcdf4 
     
    5151      SET_NF90_DEF_VAR_DEFLATE = -1 
    5252   END FUNCTION SET_NF90_DEF_VAR_DEFLATE 
     53#else 
     54      !!-------------------------------------------------------------------- 
     55      !! 'key_netcdf4' Dummy module (usually defines dummy routines for netcdf4 
     56      !!               calls when compiling without netcdf4 libraries 
     57      !!-------------------------------------------------------------------- 
     58 
     59   USE netcdf 
     60 
     61   !- netcdf4 chunking control structure 
     62   !- (optional on histbeg and histend calls) 
     63!$AGRIF_DO_NOT_TREAT 
     64   TYPE, PUBLIC :: snc4_ctl 
     65      SEQUENCE 
     66      INTEGER :: ni 
     67      INTEGER :: nj 
     68      INTEGER :: nk 
     69      LOGICAL :: luse 
     70   END TYPE snc4_ctl 
     71!$AGRIF_END_DO_NOT_TREAT 
     72 
     73CONTAINS 
     74   INTEGER FUNCTION SET_NF90_DEF_VAR_CHUNKING(nfid, nvid, ichunkalg, ichunksz) 
     75      !!-------------------------------------------------------------------- 
     76      !!                   ***  SUBROUTINE NF90_DEF_VAR_CHUNKING  *** 
     77      !! 
     78      !! ** Purpose :   Interface NetCDF4 routine to enable compiling with NetCDF4 libraries 
     79      !!                but no key_netcdf4 
     80      !!-------------------------------------------------------------------- 
     81      INTEGER,               INTENT(in) :: nfid 
     82      INTEGER,               INTENT(in) :: nvid 
     83      INTEGER,               INTENT(in) :: ichunkalg 
     84      INTEGER, DIMENSION(:), INTENT(in) :: ichunksz 
     85      !! 
     86      INTEGER                           :: iret 
     87      !! 
     88      iret = NF90_DEF_VAR_CHUNKING(nfid, nvid, ichunkalg, ichunksz) 
     89      SET_NF90_DEF_VAR_CHUNKING = iret 
     90   END FUNCTION SET_NF90_DEF_VAR_CHUNKING 
     91 
     92   INTEGER FUNCTION SET_NF90_DEF_VAR_DEFLATE(nfid, nvid, ishuffle, ideflate, ideflate_level) 
     93      !!-------------------------------------------------------------------- 
     94      !!                   ***  SUBROUTINE NF90_DEF_VAR_DEFLATE  *** 
     95      !! 
     96      !! ** Purpose :   Interface NetCDF4 routine to enable compiling with NetCDF4 libraries 
     97      !!                but no key_netcdf4 
     98      !!-------------------------------------------------------------------- 
     99      INTEGER,               INTENT(in) :: nfid 
     100      INTEGER,               INTENT(in) :: nvid 
     101      INTEGER,               INTENT(in) :: ishuffle 
     102      INTEGER,               INTENT(in) :: ideflate 
     103      INTEGER,               INTENT(in) :: ideflate_level 
     104      !! 
     105      INTEGER                           :: iret 
     106      !! 
     107      iret = NF90_DEF_VAR_DEFLATE(nfid, nvid, ishuffle, ideflate, ideflate_level) 
     108      SET_NF90_DEF_VAR_DEFLATE = iret 
     109   END FUNCTION SET_NF90_DEF_VAR_DEFLATE 
     110 
     111   SUBROUTINE GET_NF90_SYMBOL(sym_name, ivalue) 
     112      CHARACTER(len=*),      INTENT(in)  :: sym_name 
     113      INTEGER,               INTENT(out) :: ivalue 
     114      SELECT CASE (sym_name) 
     115         CASE ("NF90_HDF5") 
     116            ivalue = NF90_HDF5 
     117         CASE DEFAULT 
     118            WRITE(*,*) "Warning: unknown case in GET_NF90_SYMBOL" 
     119      END SELECT 
     120   END SUBROUTINE GET_NF90_SYMBOL 
     121#endif 
    53122 
    54123!------------------ 
  • utils/tools/DOMAINcfg/src/nemogcm.F90

    r13204 r14623  
    5454   USE lib_mpp        ! distributed memory computing 
    5555 
    56    USE lbcnfd , ONLY  : isendto, nsndto, nfsloop, nfeloop   ! Setup of north fold exchanges  
    5756 
    5857   USE agrif_connect 
    5958   USE agrif_dom_update 
    6059   USE agrif_recompute_scales 
     60 
     61   USE halo_mng 
    6162 
    6263   IMPLICIT NONE 
     
    106107       
    107108      CALL Agrif_Step_Child_adj(agrif_update_all) 
    108        
     109 
    109110      CALL Agrif_Step_Child(agrif_recompute_scalefactors) 
    110111       
     
    122123      !                            !------------------------! 
    123124      ! 
    124       IF( nstop /= 0 .AND. lwp ) THEN   ! error print 
    125          WRITE(numout,cform_err) 
    126          WRITE(numout,*) nstop, ' error have been found' 
     125      IF( nstop /= 0 .AND. lwp ) THEN        ! error print 
     126         ngrdstop = Agrif_Fixed() 
     127         WRITE(ctmp1,*) '   ==>>>   nemo_gcm: a total of ', nstop, ' errors have been found' 
     128         IF( ngrdstop > 0 ) THEN 
     129            WRITE(ctmp9,'(i2)') ngrdstop 
     130            WRITE(ctmp2,*) '           E R R O R detected in Agrif grid '//TRIM(ctmp9) 
     131            WRITE(ctmp3,*) '           Look for "E R R O R" messages in all existing '//TRIM(ctmp9)//'_ocean_output* files' 
     132            CALL ctl_stop( ' ', ctmp1, ' ', ctmp2, ' ', ctmp3 ) 
     133         ELSE 
     134            WRITE(ctmp2,*) '           Look for "E R R O R" messages in all existing ocean_output* files' 
     135            CALL ctl_stop( ' ', ctmp1, ' ', ctmp2 ) 
     136         ENDIF 
    127137      ENDIF 
    128138      ! 
     
    144154      CHARACTER(len=120), DIMENSION(60) ::   cltxt, cltxt2, clnam 
    145155      !! 
     156      NAMELIST/namctl/ sn_cfctl, ln_timing, ln_diacfl,                                & 
     157         &             nn_isplt,  nn_jsplt,  nn_ictls, nn_ictle, nn_jctls, nn_jctle   
    146158      NAMELIST/namcfg/ ln_e3_dep,                                & 
    147          &             cp_cfg, cp_cfz, jp_cfg, jpidta, jpjdta, jpkdta, jpiglo, jpjglo, & 
    148          &             jperio, ln_use_jattr, ln_domclo 
    149       !!---------------------------------------------------------------------- 
    150       ! 
     159         &             cp_cfg, cp_cfz, jp_cfg, jpidta, jpjdta, jpkdta, Ni0glo, Nj0glo, & 
     160         &             jpkglo, jperio, ln_use_jattr, ln_domclo 
     161      !!---------------------------------------------------------------------- 
     162      ! 
     163 
     164      ! 
     165      !                             !-------------------------------------------------! 
     166      !                             !     set communicator & select the local rank    ! 
     167      !                             !  must be done as soon as possible to get narea  ! 
     168      !                             !-------------------------------------------------! 
     169      ! 
     170#if defined key_iomput 
     171      IF( Agrif_Root() ) THEN 
     172         IF( lk_oasis ) THEN 
     173            CALL cpl_init( "oceanx", ilocal_comm )                               ! nemo local communicator given by oasis 
     174            CALL xios_initialize( "not used"       , local_comm =ilocal_comm )   ! send nemo communicator to xios 
     175         ELSE 
     176            CALL xios_initialize( "for_xios_mpi_id", return_comm=ilocal_comm )   ! nemo local communicator given by xios 
     177         ENDIF 
     178      ENDIF 
     179      CALL mpp_start( ilocal_comm ) 
     180#else 
     181!      IF( lk_oasis ) THEN 
     182!         IF( Agrif_Root() ) THEN 
     183!            CALL cpl_init( "oceanx", ilocal_comm )          ! nemo local communicator given by oasis 
     184!         ENDIF 
     185!         CALL mpp_start( ilocal_comm ) 
     186!      ELSE 
     187         CALL mpp_start( ) 
     188!      ENDIF 
     189#endif 
     190      ! 
     191      narea = mpprank + 1               ! mpprank: the rank of proc (0 --> mppsize -1 ) 
     192      lwm = (narea == 1)                ! control of output namelists 
     193 
    151194      cltxt = '' 
    152195      ! 
    153       !                             ! Open reference namelist and configuration namelist files 
    154       CALL ctl_opn( numnam_ref, 'namelist_ref', 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
    155       CALL ctl_opn( numnam_cfg, 'namelist_cfg', 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
    156       ! 
    157       REWIND( numnam_ref )              ! Namelist namcfg in reference namelist 
     196      ! 
     197      !                             !---------------------------------------------------------------! 
     198      !                             ! Open output files, reference and configuration namelist files ! 
     199      !                             !---------------------------------------------------------------! 
     200      ! 
     201      ! open ocean.output as soon as possible to get all output prints (including errors messages) 
     202      IF( lwm )   CALL ctl_opn(     numout,        'ocean.output', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, -1, .FALSE. ) 
     203      ! open reference and configuration namelist files 
     204                  CALL load_nml( numnam_ref,        'namelist_ref',                                           -1, lwm ) 
     205                  CALL load_nml( numnam_cfg,        'namelist_cfg',                                           -1, lwm ) 
     206      IF( lwm )   CALL ctl_opn(     numond, 'output.namelist.dyn', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, -1, .FALSE. ) 
     207      ! open /dev/null file to be able to supress output write easily 
     208      IF( Agrif_Root() ) THEN 
     209                  CALL ctl_opn(     numnul,           '/dev/null', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, -1, .FALSE. ) 
     210#ifdef key_agrif 
     211      ELSE 
     212                  numnul = Agrif_Parent(numnul)    
     213#endif 
     214      ENDIF 
     215 
    158216      READ  ( numnam_ref, namcfg, IOSTAT = ios, ERR = 903 ) 
    159 903   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namcfg in reference namelist', .TRUE. ) 
    160       REWIND( numnam_cfg )              ! Namelist namcfg in confguration namelist 
     217903   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namcfg in reference namelist') 
    161218      READ  ( numnam_cfg, namcfg, IOSTAT = ios, ERR = 904 ) 
    162 904   IF( ios >  0 )   CALL ctl_nam ( ios , 'namcfg in configuration namelist', .TRUE. )    
    163  
    164 ! Force values for AGRIF zoom (cf. agrif_user.F90) 
    165       ! 
    166       !                             !--------------------------------------------! 
    167       !                             !  set communicator & select the local node  ! 
    168       !                             !  NB: mynode also opens output.namelist.dyn ! 
    169       !                             !      on unit number numond on first proc   ! 
    170       !                             !--------------------------------------------! 
    171       ! Nodes selection (control print return in cltxt) 
    172       narea = mynode( cltxt, 'output.namelist.dyn', numnam_ref, numnam_cfg, numond , nstop ) 
    173       narea = narea + 1                                     ! mynode return the rank of proc (0 --> jpnij -1 ) 
    174  
    175       lwm = (narea == 1)                                    ! control of output namelists 
     219904   IF( ios >  0 )   CALL ctl_nam ( ios , 'namcfg in configuration namelist')  
     220 
    176221      lwp = (narea == 1)                                    ! control of all listing output print 
    177222 
     
    183228      ENDIF 
    184229 
    185         IF(lwp) THEN                            ! open listing units 
    186          ! 
    187          CALL ctl_opn( numout, 'ocean.output', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea ) 
     230      !                             !--------------------! 
     231      !                             ! Open listing units !  -> need sn_cfctl from namctl to define lwp 
     232      !                             !--------------------! 
     233      ! 
     234      READ  ( numnam_ref, namctl, IOSTAT = ios, ERR = 901 ) 
     235901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namctl in reference namelist' ) 
     236      READ  ( numnam_cfg, namctl, IOSTAT = ios, ERR = 902 ) 
     237902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namctl in configuration namelist' ) 
     238      ! 
     239      ! finalize the definition of namctl variables 
     240      IF( narea < sn_cfctl%procmin .OR. narea > sn_cfctl%procmax .OR. MOD( narea - sn_cfctl%procmin, sn_cfctl%procincr ) /= 0 )   & 
     241         &   CALL nemo_set_cfctl( sn_cfctl, .FALSE. ) 
     242      ! 
     243      lwp = (narea == 1) .OR. sn_cfctl%l_oceout    ! control of all listing output print 
     244      ! 
     245      IF(lwp) THEN                      ! open listing units 
     246         ! 
     247         IF( .NOT. lwm )   &            ! alreay opened for narea == 1 
     248            &            CALL ctl_opn( numout, 'ocean.output', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, -1, .FALSE., narea ) 
    188249         ! 
    189250         WRITE(numout,*) 
    190          WRITE(numout,*) '   CNRS - NERC - Met OFFICE - MERCATOR-ocean - INGV - CMCC' 
     251         WRITE(numout,*) '   CNRS - NERC - Met OFFICE - MERCATOR-ocean - CMCC' 
    191252         WRITE(numout,*) '                       NEMO team' 
    192253         WRITE(numout,*) '            Ocean General Circulation Model' 
     
    204265         WRITE(numout,*) "       )  )       \) |`\ \)  '.   \      (   (   " 
    205266         WRITE(numout,*) "      (  (           \_/       '-._\      )   )  " 
    206          WRITE(numout,*) "       )  )                        `     (   (   " 
     267         WRITE(numout,*) "       )  ) jgs                     `    (   (   " 
    207268         WRITE(numout,*) "     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ " 
    208269         WRITE(numout,*) 
    209270          
    210          DO ji = 1, SIZE(cltxt) 
    211             IF( TRIM(cltxt (ji)) /= '' )   WRITE(numout,*) TRIM(cltxt(ji))    ! control print of mynode 
    212          END DO 
     271         ! Print the working precision to ocean.output 
     272         IF (wp == dp) THEN 
     273            WRITE(numout,*) "Working precision = double-precision" 
     274         ELSE 
     275            WRITE(numout,*) "Working precision = single-precision" 
     276         ENDIF 
    213277         WRITE(numout,*) 
    214          WRITE(numout,*) 
    215    !      DO ji = 1, SIZE(cltxt2) 
    216    !         IF( TRIM(cltxt2(ji)) /= '' )   WRITE(numout,*) TRIM(cltxt2(ji))   ! control print of domain size 
    217    !      END DO 
    218278         ! 
    219279         WRITE(numout,cform_aaa)                                        ! Flag AAAAAAA 
    220280         ! 
    221281      ENDIF 
    222       ! open /dev/null file to be able to supress output write easily 
    223    !   CALL ctl_opn( numnul, '/dev/null', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. ) 
    224       ! 
    225       !                                      ! Domain decomposition 
    226       CALL mpp_init                          ! MPP 
     282      ! 
     283      IF(lwm) WRITE( numond, namctl ) 
     284      ! 
     285      !                             !-----------------------------------------! 
     286      !                             ! mpp parameters and domain decomposition ! 
     287      !                             !-----------------------------------------! 
     288      CALL mpp_init 
     289      CALL halo_mng_init() 
     290      ! Now we know the dimensions of the grid and numout has been set: we can allocate arrays 
    227291 
    228292 !    IF( Agrif_Root() ) THEN 
     
    268332      ! 
    269333      IF( numstp          /= -1 )   CLOSE( numstp          )   ! time-step file 
    270       IF( numnam_ref      /= -1 )   CLOSE( numnam_ref      )   ! oce reference namelist 
    271       IF( numnam_cfg      /= -1 )   CLOSE( numnam_cfg      )   ! oce configuration namelist 
    272334      IF( lwm.AND.numond  /= -1 )   CLOSE( numond          )   ! oce output namelist 
    273335      IF( numout          /=  6 )   CLOSE( numout          )   ! standard model output file 
     
    299361   END SUBROUTINE nemo_alloc 
    300362 
     363   SUBROUTINE nemo_set_cfctl(sn_cfctl, setto ) 
     364      !!---------------------------------------------------------------------- 
     365      !!                     ***  ROUTINE nemo_set_cfctl  *** 
     366      !! 
     367      !! ** Purpose :   Set elements of the output control structure to setto. 
     368      !! 
     369      !! ** Method  :   Note this routine can be used to switch on/off some 
     370      !!                types of output for selected areas. 
     371      !!---------------------------------------------------------------------- 
     372      TYPE(sn_ctl), INTENT(inout) :: sn_cfctl 
     373      LOGICAL     , INTENT(in   ) :: setto 
     374      !!---------------------------------------------------------------------- 
     375      sn_cfctl%l_runstat = setto 
     376      sn_cfctl%l_trcstat = setto 
     377      sn_cfctl%l_oceout  = setto 
     378      sn_cfctl%l_layout  = setto 
     379      sn_cfctl%l_prtctl  = setto 
     380      sn_cfctl%l_prttrc  = setto 
     381      sn_cfctl%l_oasout  = setto 
     382   END SUBROUTINE nemo_set_cfctl 
    301383 
    302384   SUBROUTINE nemo_partition( num_pes ) 
     
    412494   END SUBROUTINE factorise 
    413495 
    414  
    415    SUBROUTINE nemo_northcomms 
    416       !!---------------------------------------------------------------------- 
    417       !!                     ***  ROUTINE  nemo_northcomms  *** 
    418       !! ** Purpose :   Setup for north fold exchanges with explicit  
    419       !!                point-to-point messaging 
    420       !! 
    421       !! ** Method :   Initialization of the northern neighbours lists. 
    422       !!---------------------------------------------------------------------- 
    423       !!    1.0  ! 2011-10  (A. C. Coward, NOCS & J. Donners, PRACE) 
    424       !!    2.0  ! 2013-06 Setup avoiding MPI communication (I. Epicoco, S. Mocavero, CMCC)  
    425       !!---------------------------------------------------------------------- 
    426       INTEGER  ::   sxM, dxM, sxT, dxT, jn 
    427       INTEGER  ::   njmppmax 
    428       !!---------------------------------------------------------------------- 
    429       ! 
    430       njmppmax = MAXVAL( njmppt ) 
    431       ! 
    432       !initializes the north-fold communication variables 
    433       isendto(:) = 0 
    434       nsndto     = 0 
    435       ! 
    436       !if I am a process in the north 
    437       IF ( njmpp == njmppmax ) THEN 
    438           !sxM is the first point (in the global domain) needed to compute the 
    439           !north-fold for the current process 
    440           sxM = jpiglo - nimppt(narea) - nlcit(narea) + 1 
    441           !dxM is the last point (in the global domain) needed to compute the 
    442           !north-fold for the current process 
    443           dxM = jpiglo - nimppt(narea) + 2 
    444  
    445           !loop over the other north-fold processes to find the processes 
    446           !managing the points belonging to the sxT-dxT range 
    447    
    448           DO jn = 1, jpni 
    449                 !sxT is the first point (in the global domain) of the jn 
    450                 !process 
    451                 sxT = nfiimpp(jn, jpnj) 
    452                 !dxT is the last point (in the global domain) of the jn 
    453                 !process 
    454                 dxT = nfiimpp(jn, jpnj) + nfilcit(jn, jpnj) - 1 
    455                 IF ((sxM .gt. sxT) .AND. (sxM .lt. dxT)) THEN 
    456                    nsndto = nsndto + 1 
    457                      isendto(nsndto) = jn 
    458                 ELSEIF ((sxM .le. sxT) .AND. (dxM .ge. dxT)) THEN 
    459                    nsndto = nsndto + 1 
    460                      isendto(nsndto) = jn 
    461                 ELSEIF ((dxM .lt. dxT) .AND. (sxT .lt. dxM)) THEN 
    462                    nsndto = nsndto + 1 
    463                      isendto(nsndto) = jn 
    464                 END IF 
    465           END DO 
    466           nfsloop = 1 
    467           nfeloop = nlci 
    468           DO jn = 2,jpni-1 
    469            IF(nfipproc(jn,jpnj) .eq. (narea - 1)) THEN 
    470               IF (nfipproc(jn - 1 ,jpnj) .eq. -1) THEN 
    471                  nfsloop = nldi 
    472               ENDIF 
    473               IF (nfipproc(jn + 1,jpnj) .eq. -1) THEN 
    474                  nfeloop = nlei 
    475               ENDIF 
    476            ENDIF 
    477         END DO 
    478  
    479       ENDIF 
    480 #if defined key_mpp_mpi 
    481       l_north_nogather = .TRUE. 
    482 #endif 
    483    END SUBROUTINE nemo_northcomms 
    484  
    485  
    486496   !!====================================================================== 
    487497END MODULE nemogcm 
  • utils/tools/DOMAINcfg/src/par_kind.f90

    r9598 r14623  
    2424   INTEGER, PUBLIC, PARAMETER ::   sp = SELECTED_REAL_KIND( 6, 37)   !: single precision (real 4) 
    2525   INTEGER, PUBLIC, PARAMETER ::   dp = SELECTED_REAL_KIND(12,307)   !: double precision (real 8) 
     26# if defined key_single 
     27   INTEGER, PUBLIC, PARAMETER ::   wp = sp                              !: working precision 
     28# else 
    2629   INTEGER, PUBLIC, PARAMETER ::   wp = dp                              !: working precision 
     30# endif 
    2731 
    2832   !                                                                !!** Integer ** 
     
    3135    
    3236   !                                                                !!** Integer ** 
    33    INTEGER, PUBLIC, PARAMETER ::   lc = 256                          !: Lenght of Character strings 
     37   INTEGER, PUBLIC, PARAMETER ::   lc  = 256                          !: Lenght of Character strings 
     38   INTEGER, PUBLIC, PARAMETER ::   lca = 400                          !: Lenght of Character arrays 
    3439 
    3540   !!---------------------------------------------------------------------- 
    36    !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    37    !! $Id: par_kind.F90 2528 2010-12-27 17:33:53Z rblod $  
    38    !! Software governed by the CeCILL licence     (./LICENSE) 
     41   !! NEMO 3.3 , NEMO Consortium (2018) 
     42   !! $Id: par_kind.F90 13226 2020-07-02 14:24:31Z orioltp $  
     43   !! Software governed by the CeCILL license (see ./LICENSE) 
    3944   !!---------------------------------------------------------------------- 
    4045END MODULE par_kind 
  • utils/tools/DOMAINcfg/src/par_oce.f90

    r14199 r14623  
    2828   !!                   namcfg namelist parameters 
    2929   !!---------------------------------------------------------------------- 
    30    LOGICAL       ::   ln_read_cfg = .FALSE.      !: (=T) read the domain configuration file or (=F) not 
     30   LOGICAL       ::   ln_read_cfg      !: (=T) read the domain configuration file or (=F) not 
    3131   CHARACTER(lc) ::      cn_domcfg        !: filename the configuration file to be read 
    3232   LOGICAL       ::   ln_write_cfg     !: (=T) create the domain configuration file 
     
    4444   !! Domain Matrix size  
    4545   !!--------------------------------------------------------------------- 
     46 
     47   ! time dimension 
     48   INTEGER, PUBLIC, PARAMETER :: jpt = 3    !: time dimension 
     49 
    4650   ! global domain size               !!! * total computational domain * 
    4751   INTEGER       ::   jpiglo           !: 1st dimension of global domain --> i-direction 
     
    8589   INTEGER, PUBLIC, PARAMETER ::   jpr2di = 0   !: number of columns for extra outer halo  
    8690   INTEGER, PUBLIC, PARAMETER ::   jpr2dj = 0   !: number of rows    for extra outer halo  
    87    INTEGER, PUBLIC, PARAMETER ::   nn_hls = 1   !: halo width (applies to both rows and columns) 
    8891 
     92   ! halo with and starting/inding DO-loop indices 
     93   INTEGER, PUBLIC ::   nn_hls   !: halo width (applies to both rows and columns) 
     94   INTEGER, PUBLIC ::   Nis0, Nis1, Nis1nxt2, Nis2   !: start I-index (_0: without halo, _1 or _2: with 1 or 2 halos) 
     95   INTEGER, PUBLIC ::   Nie0, Nie1, Nie1nxt2, Nie2   !: end   I-index (_0: without halo, _1 or _2: with 1 or 2 halos) 
     96   INTEGER, PUBLIC ::   Njs0, Njs1, Njs1nxt2, Njs2   !: start J-index (_0: without halo, _1 or _2: with 1 or 2 halos) 
     97   INTEGER, PUBLIC ::   Nje0, Nje1, Nje1nxt2, Nje2   !: end   J-index (_0: without halo, _1 or _2: with 1 or 2 halos) 
     98   INTEGER, PUBLIC ::   Ni_0, Nj_0, Ni_1, Nj_1, Ni_2, Nj_2   !: domain size (_0: without halo, _1 or _2: with 1 or 2 halos) 
     99   INTEGER, PUBLIC ::   Ni0glo, Nj0glo 
     100    
    89101   !!---------------------------------------------------------------------- 
    90102   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
  • utils/tools/DOMAINcfg/src/stringop.f90

    r6951 r14623  
    11MODULE stringop 
     2!$AGRIF_DO_NOT_TREAT 
    23!- 
    34!$Id: stringop.f90 2281 2010-10-15 14:21:13Z smasson $ 
     
    183184!=== 
    184185!------------------ 
     186!$AGRIF_END_DO_NOT_TREAT 
    185187END MODULE stringop 
Note: See TracChangeset for help on using the changeset viewer.