MODULE CPLNG_CONFIG_MOD

    IMPLICIT NONE

    PRIVATE

    PUBLIC CPLNG_CONFIG

CONTAINS

SUBROUTINE CPLNG_CONFIG

    USE PARKIND1, ONLY: JPIM, JPRB

    USE YOMLUN   , ONLY : NULOUT

    USE MOD_OASIS

    USE CPLNG_DATA_MOD

    USE YOMGEM,     ONLY: NGPTOT
    USE YOMDIM,     ONLY: NSMAX, NUMP, NSPEC2
    USE YOMMP,      ONLY: NGLOBALINDEX
    USE YOMLAP,     ONLY: MYMS
    USE YOMDIM,     ONLY: NFLEVG, NFLEVL
    USE SURFACE_FIELDS_MIX, ONLY: YSP_SBD
    USE YOERAD,     ONLY: NSW, LTM5AER, LTM5O3, LTM5CH4, LTM5CO2FB
    USE YOMECEARTH, ONLY: LTM5, LLPJG, LLPJGFB, LAMIP

    TYPE NODE_TYPE
        TYPE(CPLNG_FLD_TYPE),POINTER :: THIS
        TYPE(NODE_TYPE),     POINTER :: NEXT
    END TYPE NODE_TYPE
    TYPE(NODE_TYPE),POINTER :: TMP_FLD_LIST=>NULL()
    TYPE(NODE_TYPE),POINTER :: PTR

    ! Variables needed in OASIS calls
    INTEGER(KIND=JPIM)              :: IERROR
    INTEGER(KIND=JPIM), ALLOCATABLE :: IG_PARAL(:)
    INTEGER(KIND=JPIM)              :: IL_PART_ID, IL_PART_ID_GP, IL_PART_ID_SP
    INTEGER(KIND=JPIM)              :: IVAR_NODIMS(2)
    INTEGER(KIND=JPIM)              :: IVAR_ACTUAL_SHAPE(2)

    ! Number of ice categories (for NEMO/LIM3 coupling)
    INTEGER(KIND=JPIM),PARAMETER :: NUMICECAT = 5
 
    ! TM5 3D fields: is the vertical remapping done in IFS?
    LOGICAL,PARAMETER  :: REDUCED_TO_TM5_LEVELS = .TRUE.
    ! Number of merged IFS layers per TM5 layer
    INTEGER(KIND=JPIM),ALLOCATABLE :: MERGED_LEVELS(:)

    ! Are the aerosol fields received from TM5 cut off?
    LOGICAL,PARAMETER  :: CUTOFF_TM5_AER_LEVELS  = .TRUE.

    INTEGER(KIND=JPIM) :: ILEV

    LOGICAL            :: LSEGSTART(NGPTOT)
    INTEGER(KIND=JPIM) :: II,IP
    INTEGER(KIND=JPIM) :: ILVL,ICAT
    INTEGER(KIND=JPIM) :: IOFFSET
    INTEGER(KIND=JPIM) :: IEXTENT
    INTEGER(KIND=JPIM) :: INUMSEGMENTS
    CHARACTER(LEN=128) :: CFLDNAME
    CHARACTER(LEN=3)   :: CERRSTR

    INTEGER(KIND=JPIM) :: ISPM
    
#include "abor1.intfb.h"
    
    ! -------------------------------------------------------------------------
    ! * (0) Early exit if CPLNG not active
    ! -------------------------------------------------------------------------
    IF (.NOT.CPLNG_ACTIVE) RETURN

    ! -------------------------------------------------------------------------
    ! * (1) CONFIGURE COUPLING FIELDS
    ! -------------------------------------------------------------------------
    IF(.NOT.LAMIP)THEN
       ! Fields sent from atmosphere to ocean
       CALL ADD_FLD('A_TauX_oce',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_TauY_oce',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_TauX_ice',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_TauY_ice',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Qs_mix',        CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Qs_ice',        CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Qns_mix',       CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Qns_ice',       CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Precip_liquid', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Precip_solid',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Evap_total',    CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Evap_ice',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_dQns_dT',       CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Runoff',        CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)
       CALL ADD_FLD('A_Calving',       CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_OCE)

       ! Fields received by the atmosphere from the ocean
       CALL ADD_FLD('A_SST',           CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_OCE)
       CALL ADD_FLD('A_Ice_temp',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_OCE)
       CALL ADD_FLD('A_Ice_albedo',    CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_OCE)
       CALL ADD_FLD('A_Ice_frac',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_OCE)
       CALL ADD_FLD('A_Ice_thickness', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_OCE)
       CALL ADD_FLD('A_Snow_thickness',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_OCE)
    ENDIF

    IF(LAMIP)THEN
       ! Fields received by the atmosphere from the ocean
       CALL ADD_FLD('A_SST',           CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_AMIP)
       CALL ADD_FLD('A_Ice_frac',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN ,CPLNG_STAGE_RCV_AMIP)
    ENDIF
    
    IF(LTM5)THEN
       !
       ! (1.1) Configure the vertical remapping between NFLEVG (ifs) and NLEV_TM5 (tm5)
       !
       IF (REDUCED_TO_TM5_LEVELS) THEN
          IF (NFLEVG == 91) THEN
            IF ((NLEV_TM5 /= 34).AND.(NLEV_TM5 /= 10).AND.(NLEV_TM5 /= 4)) THEN
               CALL ABOR1("CPLNG_CONFIG: 4, 10 or 34 levels expected in TM5.")
             ENDIF
          ELSE IF (NFLEVG == 62) THEN
            IF (NLEV_TM5 /= 31) THEN
              CALL ABOR1("CPLNG_CONFIG: 31 levels expected in TM5.")
            ENDIF
          ELSE
             CALL ABOR1("CPLNG_CONFIG: Merging of layers applied in TM5 not defined for this vertical grid.")
          ENDIF
       ELSE
         IF (NLEV_TM5 /= NFLEVG) THEN
           WRITE (CERRSTR,'(I3)') NFLEVG
           CALL ABOR1("CPLNG_CONFIG: "//CERRSTR//" levels expected in TM5.")
         ENDIF
       ENDIF

       ! For aerosols the number of levels received from TM5 is NLEV_TM5_AER,
       ! which may be lower than NLEV_TM5.
       ! The cutoff level is set by tm5_exch_nlevs_cutoff in ece-esm.sh(.tmpl).
       ! It is currently assumed that, when a cutoff is applied,
       ! it is set to the top level of the convection in TM5 (lmax_conv).
       IF (CUTOFF_TM5_AER_LEVELS .AND. (.NOT.LTM5CO2)) THEN
          IF (NLEV_TM5 == 34) THEN
             NLEV_TM5_AER=23
          ELSE IF (NLEV_TM5 == 31) THEN
             NLEV_TM5_AER=28
          ELSE IF (NLEV_TM5 == 91) THEN
             NLEV_TM5_AER= 58
          ELSE IF (NLEV_TM5 == 62) THEN
             NLEV_TM5_AER=55
          ELSE IF (NLEV_TM5 == 40) THEN
             NLEV_TM5_AER=37
          ELSE
             CALL ABOR1("CPLNG_CONFIG: Cutoff of TM5 aerosol fields not defined for this vertical grid.")
          ENDIF
       ELSE
          NLEV_TM5_AER=NLEV_TM5
       ENDIF

       ALLOCATE(LEV_IDX_TM5(NFLEVG))
       ALLOCATE(LEV_IDX_MIN(NLEV_TM5))
       ALLOCATE(LEV_IDX_MAX(NLEV_TM5))

       IF (REDUCED_TO_TM5_LEVELS) THEN
          ALLOCATE(MERGED_LEVELS(NLEV_TM5))
          IF (NFLEVG == 91 .AND. NLEV_TM5 == 34) THEN
             MERGED_LEVELS(1:NLEV_TM5)=(/ 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, &
                                          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, &
                                          2, 2, 3, 3, 3, 3, 3, 3, 3, 3, &
                                          3, 3, 3, 2 /)
          ENDIF
          IF (NFLEVG == 91 .AND. NLEV_TM5 == 10) THEN
             MERGED_LEVELS(1:NLEV_TM5)=(/ 14, 12, 8, 12, 13, 9, 12, 6, 3, 2 /)
          ENDIF
          IF (NFLEVG == 91 .AND. NLEV_TM5 == 4) THEN
            MERGED_LEVELS(1:NLEV_TM5)=(/ 46, 28, 15, 2 /)
          ENDIF
          IF (NFLEVG == 62 .AND. NLEV_TM5 == 31) THEN
             MERGED_LEVELS(1:NLEV_TM5)=(/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, &
                                          1, 2, 2, 2, 2, 2, 2, 2, 2, 3, &
                                          3, 3, 3, 3, 3, 3, 3, 3, 3, 3, &
                                          2 /)
          ENDIF
          LEV_IDX_MIN(1) = 1
          LEV_IDX_MAX(1) = MERGED_LEVELS(1)
          LEV_IDX_TM5(1:MERGED_LEVELS(1)) = 1
          DO ILEV= 2, NLEV_TM5
             LEV_IDX_MIN(ILEV) = LEV_IDX_MAX(ILEV-1)+1
             LEV_IDX_MAX(ILEV) = LEV_IDX_MIN(ILEV)+MERGED_LEVELS(ILEV)-1
             LEV_IDX_TM5(LEV_IDX_MIN(ILEV):LEV_IDX_MAX(ILEV))=ILEV
          ENDDO
          DEALLOCATE(MERGED_LEVELS)
       ELSE
          DO ILEV=1,NFLEVG
             LEV_IDX_TM5(ILEV)=ILEV
             LEV_IDX_MIN(ILEV)=ILEV
             LEV_IDX_MAX(ILEV)=ILEV
          ENDDO
       ENDIF

       !
       ! (1.2) Configure fields sent to the atmospheric chemistry module
       !
        CALL ADD_FLD('A_LNSP',  CPLNG_FLD_TYPE_SPECTRAL, OASIS_OUT,CPLNG_STAGE_SND_CHE)
        CALL ADD_FLD('A_VOR',   CPLNG_FLD_TYPE_SPECTRAL, OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_DIV',   CPLNG_FLD_TYPE_SPECTRAL, OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_OROG',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        CALL ADD_FLD('A_SPRES', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        CALL ADD_FLD('A_TMP',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_HUM',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        IF(.NOT.LTM5CO2)THEN
           CALL ADD_FLD('A_CLW',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
           CALL ADD_FLD('A_CIW',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
           CALL ADD_FLD('A_CC',    CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
           CALL ADD_FLD('A_CCO',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
           CALL ADD_FLD('A_CCU',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        ENDIF
        CALL ADD_FLD('A_UMF',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_UDR',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_DMF',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_DDR',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE,LVL=NLEV_TM5)
        CALL ADD_FLD('A_LSMSK', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        IF(.NOT.LTM5CO2)THEN
           CALL ADD_FLD('A_ALB',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        ENDIF
        CALL ADD_FLD('A_SR',    CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        IF(.NOT.LTM5CO2)THEN
           CALL ADD_FLD('A_CI',      CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_SSTChem', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        ENDIF
        CALL ADD_FLD('A_WSPD',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        IF(.NOT.LTM5CO2) THEN
           CALL ADD_FLD('A_SRC',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_D2M',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_T2M',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        ENDIF
        CALL ADD_FLD('A_SLHF',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        CALL ADD_FLD('A_SSHF',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        CALL ADD_FLD('A_EWSS',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        CALL ADD_FLD('A_NSSS',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        IF(.NOT.LTM5CO2)THEN
           CALL ADD_FLD('A_CP',    CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_LSP',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_SSR',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_SD',    CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV01',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV02',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV03',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV04',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV05',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV06',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV07',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV09',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV10',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV11',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV13',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV16',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV17',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV18',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_TV19',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_CVL',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_CVH',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
           CALL ADD_FLD('A_SWVL1', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
        ENDIF

! NOT USED YET
!        CALL ADD_FLD('SKTChe__',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)
!        CALL ADD_FLD('SFChe___',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_CHE)

        ! Fields received from the atmospheric chemistry module
        IF (LTM5O3) THEN
            CALL ADD_FLD('A_O3',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5)
        ENDIF
        IF (LTM5CH4) THEN
            CALL ADD_FLD('A_CH4',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5)
        ENDIF
        IF (LTM5CO2FB) THEN
          CALL ADD_FLD('A_CO2',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5)
        ENDIF
        IF (LTM5AER) THEN
            ! Particle number mixing ratios per mode (NxChe) are received in TM5 units
            !CALL ADD_FLD('A_N1',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            !CALL ADD_FLD('A_SU1',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_N2',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SU2',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_BC2',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_OM2',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_N3',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SU3',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_BC3',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_OM3',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SS3',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_DD3',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_N4',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SU4',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_BC4',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_OM4',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SS4',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_DD4',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_N5',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_BC5',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_OM5',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_N6',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_DD6',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_N7',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_DD7',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_NO3',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_MSA',  CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_01', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_02', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_03', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_04', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_05', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_06', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_07', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_08', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_09', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_10', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_11', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_12', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_13', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_AOD_14', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_01', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_02', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_03', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_04', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_05', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_06', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_07', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_08', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_09', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_10', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_11', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_12', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_13', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_SSA_14', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_01', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_02', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_03', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_04', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_05', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_06', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_07', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_08', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_09', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_10', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_11', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_12', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_13', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
            CALL ADD_FLD('A_ASF_14', CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_CHE,LVL=NLEV_TM5_AER)
        ENDIF ! LTM5AER
    ENDIF ! LTM5

    IF (LLPJG) THEN

        CALL ADD_FLD('T2MVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        CALL ADD_FLD('SSRVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        CALL ADD_FLD('SLRVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        CALL ADD_FLD('SoilMVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG,LVL=YSP_SBD%NLEVS)
        CALL ADD_FLD('SoilTVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG,LVL=YSP_SBD%NLEVS)
        CALL ADD_FLD('SDensVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        CALL ADD_FLD('SDVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        CALL ADD_FLD('TPVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        !CLNCALL ADD_FLD('CVLVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        !CLNCALL ADD_FLD('CVHVeg',   CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)
        !CLNCALL ADD_FLD('TVLVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_OUT,CPLNG_STAGE_SND_VEG)

        ! Receive fields from LPJ-GUESS even if they're not used
        CALL ADD_FLD('LAILVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_VEG)
        CALL ADD_FLD('LAIHVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_VEG)
        CALL ADD_FLD('TypeHVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_VEG)
        CALL ADD_FLD('FracHVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_VEG)
        CALL ADD_FLD('TypeLVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_VEG)
        CALL ADD_FLD('FracLVeg',CPLNG_FLD_TYPE_GRIDPOINT,OASIS_IN,CPLNG_STAGE_RCV_VEG)

    ENDIF ! LLPJG

    ! -------------------------------------------------------------------------
    ! * (2) Provide array of coupling fields (CPLNG_FLD)
    ! -------------------------------------------------------------------------
    IF (.NOT.ASSOCIATED(TMP_FLD_LIST)) CALL ABOR1("CPLNG_CONFIG: No coupling fields configured.")

    ! Count members in TMP_FLD_LIST
    II = 1
    PTR => TMP_FLD_LIST
    DO WHILE(ASSOCIATED(PTR%NEXT))
        II = II+1
        PTR => PTR%NEXT
    ENDDO

    ALLOCATE(CPLNG_FLD(II))

    ! Copy fields to array, destroy temporary list
    DO II=1,SIZE(CPLNG_FLD)
        CPLNG_FLD(II) = TMP_FLD_LIST%THIS
        PTR          => TMP_FLD_LIST
        TMP_FLD_LIST => TMP_FLD_LIST%NEXT
        DEALLOCATE(PTR)
    ENDDO

    ! -------------------------------------------------------------------------
    ! * (3) SET UP OASIS PARTITION
    ! -------------------------------------------------------------------------

    ! * (3A) Grid point fields
    IF( ANY(CPLNG_FLD(:)%TYPE == CPLNG_FLD_TYPE_GRIDPOINT) )THEN

        ! Set up logical array LSEGSTART that indicats where OASIS segments start
        ! Method: Use the NGLOBALINDEX array from YOMMP that contains a
        !         local-to-global mapping of the grid points. If two consecutive
        !         indices in this array differ by any other value than one, it's the
        !         start of a new segment.
        LSEGSTART(1)        = .TRUE.
        LSEGSTART(2:NGPTOT) = NGLOBALINDEX(2:NGPTOT)-NGLOBALINDEX(1:NGPTOT-1) /= 1

        INUMSEGMENTS = COUNT(LSEGSTART) ! Counts number of segments

        ! For shape and meaning of IG_PARAL, see OASIS documentation
        ALLOCATE(IG_PARAL(2 + 2*INUMSEGMENTS))

        IG_PARAL(1) = 3 ! Value 3 indicates an orange partition, which is
                        ! an ensemble of segments of the global domain
        IG_PARAL(2) = INUMSEGMENTS

        ! Compute segment offsets and extents and store them in IG_PARAL for later
        ! use in the OASIS_DEF_PARTITION call
        IOFFSET = NGLOBALINDEX(1)
        IEXTENT = 1
        IP      = 3 ! Pointer into IG_PARAL array
        DO II=2,NGPTOT
            IF (LSEGSTART(II)) THEN
                ! OASIS counts offsets starting with zero, hence minus one
                IG_PARAL(IP)   = IOFFSET-1
                IG_PARAL(IP+1) = IEXTENT
                IP = IP+2
                IOFFSET = NGLOBALINDEX(II)
                IEXTENT = 1
            ELSE
                IEXTENT = IEXTENT+1
            ENDIF
        ENDDO
        IG_PARAL(IP)   = IOFFSET-1
        IG_PARAL(IP+1) = IEXTENT

        ! Define partition for OASIS
        CALL OASIS_DEF_PARTITION(IL_PART_ID_GP,IG_PARAL,IERROR)
        IF (IERROR/=OASIS_OK) THEN
            WRITE (CERRSTR,'(I3)') IERROR
            CALL ABOR1("CPLNG_CONFIG: Error on OASIS_DEF_PARTITION (gridpoint): "//CERRSTR)
        ENDIF

        DEALLOCATE(IG_PARAL)

    ENDIF ! Field type == gridpoint

    ! * (3B) Spectral fields
    IF( ANY(CPLNG_FLD(:)%TYPE == CPLNG_FLD_TYPE_SPECTRAL) )THEN
       !
       ! Orange partition: each processor owns a number of (not following) wave numbers.
       !
       !  yomdim/NSMAX        : Spectral truncation T
       !  yomdim/NUMP         : Number of wavenumbers locally
       !  yomlap/MYMS(1:NUMP) : Actual wave numbers   (NOTE: not 0:NUMP as in comment!)

       ! Allocate definition array
       ALLOCATE( IG_PARAL(2+2*NUMP) )

       ! Indicator for orange partition
       IG_PARAL(1) = 3

       ! Number of segments
       IG_PARAL(2) = NUMP

       ! Global offset and size
       DO II = 1, NUMP
          ! Global wave number
          ISPM = MYMS(II)
          ! Offset
          IG_PARAL(1+II*2) = ((NSMAX+1)+(NSMAX+2-ISPM)) * ISPM
          ! Size
          IG_PARAL(2+II*2) = (NSMAX+1-ISPM)*2  ! M:T, Re/Im
       END DO

       ! Define partition for OASIS
       CALL OASIS_DEF_PARTITION(IL_PART_ID_SP,IG_PARAL,IERROR)
       IF (IERROR/=OASIS_OK) THEN
          WRITE (CERRSTR,'(I3)') IERROR
          CALL ABOR1("CPLNG_CONFIG: Error on OASIS_DEF_PARTITION (spectral): "//CERRSTR)
       ENDIF

       DEALLOCATE(IG_PARAL)

    ENDIF ! Field type == spectral

    ! -------------------------------------------------------------------------
    ! * (4) DEFINE COUPLING FIELDS FOR OASIS
    ! -------------------------------------------------------------------------
    IVAR_NODIMS = (/ 1, 1 /)

    DO II=1,SIZE(CPLNG_FLD)

        ! Allocate for ID's of all levels/categories of the field
        ALLOCATE(CPLNG_FLD(II)%ID(CPLNG_FLD(II)%NUM_LVL,CPLNG_FLD(II)%NUM_CAT))

        ! Set OASIS partition id and data size according to field type
        ! (gp/spectral). Allocate data member.
        SELECT CASE (CPLNG_FLD(II)%TYPE)

        CASE (CPLNG_FLD_TYPE_GRIDPOINT)
            IL_PART_ID        = IL_PART_ID_GP
            IVAR_ACTUAL_SHAPE = (/ 1, NGPTOT /)
            ALLOCATE(CPLNG_FLD(II)%D(NGPTOT,                &
            &                        CPLNG_FLD(II)%NUM_LVL, &
            &                        CPLNG_FLD(II)%NUM_CAT  ))

        CASE (CPLNG_FLD_TYPE_SPECTRAL )
            IL_PART_ID        = IL_PART_ID_SP
            IVAR_ACTUAL_SHAPE = (/ 1, NSPEC2 /)
            ALLOCATE(CPLNG_FLD(II)%D(NSPEC2,                &
            &                        CPLNG_FLD(II)%NUM_LVL, &
            &                        CPLNG_FLD(II)%NUM_CAT  ))

        CASE DEFAULT
            CALL ABOR1("CPLNG_CONFIG: Wrong field type for " // TRIM(CPLNG_FLD(II)%NAME))

        END SELECT

        ! Initialise to a strange value
        CPLNG_FLD(II)%D = -HUGE(0.0_JPRB)

        DO ICAT=1,CPLNG_FLD(II)%NUM_CAT
            DO ILVL=1,CPLNG_FLD(II)%NUM_LVL

                CFLDNAME = TRIM(CPLNG_FLD(II)%NAME)
                IF (CPLNG_FLD(II)%NUM_CAT>1) WRITE (CFLDNAME,'(A,".C",I3.3)') TRIM(CFLDNAME),ICAT
                IF (CPLNG_FLD(II)%NUM_LVL>1) WRITE (CFLDNAME,'(A,".L",I3.3)') TRIM(CFLDNAME),ILVL

                CALL OASIS_DEF_VAR(CPLNG_FLD(II)%ID(ILVL,ICAT), &
                &                  CFLDNAME,                    &
                &                  IL_PART_ID,                  &
                &                  IVAR_NODIMS,                 &
                &                  CPLNG_FLD(II)%INOUT,         &
                &                  IVAR_ACTUAL_SHAPE,           &
                &                  OASIS_REAL,                  &
                &                  IERROR                       )
                IF (IERROR/=OASIS_OK) THEN
                    WRITE (CERRSTR,'(I3)') IERROR
                    CALL ABOR1("CPLNG_CONFIG: Error in OASIS_DEF_VAR: " // CERRSTR // &
                    &          " (" // TRIM(CFLDNAME) // ")")
                ENDIF
            ENDDO
        ENDDO
    ENDDO

    ! -------------------------------------------------------------------------
    ! * (5) FINALISE OASIS DEFINITION PHASE
    ! -------------------------------------------------------------------------
    CALL OASIS_ENDDEF(IERROR)
    IF (IERROR/=OASIS_OK) THEN
        WRITE (CERRSTR,'(I3)') IERROR
        CALL ABOR1("CPLNG_CONFIG: Error in OASIS_ENDDEF: "//CERRSTR)
    ENDIF

contains

    SUBROUTINE ADD_FLD(NAME,TYPE,INOUT,STAGE,LVL,CAT)

        ! Arguments
        CHARACTER(LEN=*),  INTENT(IN)          :: NAME
        INTEGER(KIND=JPIM),INTENT(IN)          :: TYPE
        INTEGER(KIND=JPIM),INTENT(IN)          :: INOUT
        INTEGER(KIND=JPIM),INTENT(IN)          :: STAGE
        INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: LVL
        INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: CAT

        ! Locals
        INTEGER(KIND=JPIM)      :: NUM_LVL,NUM_CAT
        TYPE(NODE_TYPE),POINTER :: NEW,PTR

        NUM_LVL = 1
        NUM_CAT = 1

        IF (PRESENT(LVL)) NUM_LVL = LVL
        IF (PRESENT(CAT)) NUM_CAT = CAT

        ALLOCATE(NEW)
        NEW%NEXT => NULL()

        ALLOCATE(NEW%THIS)
        NEW%THIS%NAME    = NAME
        NEW%THIS%TYPE    = TYPE
        NEW%THIS%INOUT   = INOUT
        NEW%THIS%STAGE   = STAGE
        NEW%THIS%NUM_LVL = NUM_LVL
        NEW%THIS%NUM_CAT = NUM_CAT

        IF (ASSOCIATED(TMP_FLD_LIST)) THEN
            PTR => TMP_FLD_LIST
            DO WHILE(ASSOCIATED(PTR%NEXT))
                PTR => PTR%NEXT
            ENDDO
            PTR%NEXT => NEW
        ELSE
            TMP_FLD_LIST => NEW
        ENDIF

    END SUBROUTINE ADD_FLD

END SUBROUTINE CPLNG_CONFIG

END MODULE CPLNG_CONFIG_MOD
