!
! $Id: radlwsw_m.F90 6127 2026-03-26 13:59:25Z idelkadi $
!
MODULE lmdz_rad_out_m
  IMPLICIT NONE
CONTAINS

  SUBROUTINE lmdz_rad_out( &
                           iof,PWV, &
                           ZFSUP,ZFSDN,ZFSUP0,ZFSDN0, &
                           ZFSUPC0,ZFSDNC0,ZFLUP,ZFLDN, &
                           ZFLUP0,ZFLDN0,ZFLUPC0,ZFLDNC0, &
                           zheat,zcool,zheat0,zcool0,zheat_volc,zcool_volc, &
                           ztopsw,ztoplw,zsolsw,zsollw,zalbpla,zsolswfdiff, &
                           zsollwdown,ztopsw0,ztoplw0,zsolsw0,zsollw0, &
                           ztopswadaero,zsolswadaero,ztopswad0aero,zsolswad0aero, &
                           ztopswaiaero,zsolswaiaero,ztoplwadaero,zsollwadaero, &
                           ztoplwad0aero,zsollwad0aero,ztoplwaiaero,zsollwaiaero, &
                           ztopsw_aero,ztopsw0_aero,zsolsw_aero,zsolsw0_aero, &
                           ztopswcf_aero,zsolswcf_aero, &
                           heat,heat0,cool,cool0,albpla,heat_volc, cool_volc,&
                           topsw,toplw,solsw,solswfdiff,sollw,sollwdown,&
                           topsw0,toplw0,solsw0,sollw0,&
                           lwdnc0,lwdn0,lwdn,lwupc0,lwup0,lwup,&
                           swdnc0,swdn0,swdn,swupc0,swup0,swup,&
                           topswad_aero,solswad_aero,topswai_aero,solswai_aero, &
                           topswad0_aero,solswad0_aero,topsw_aero,topsw0_aero,&
                           solsw_aero,solsw0_aero,topswcf_aero,solswcf_aero,&
                           toplwad_aero,sollwad_aero,toplwai_aero,sollwai_aero, &
                           toplwad0_aero,sollwad0_aero, &
                           cloud_cover_sw,ZFLUX_DIR,ZFLUX_DIR_CLEAR,ZFLUX_DIR_INTO_SUN)

    !==================================================================================================
    ! A. Idelkadi, mars 2026 : 
    !                          Recriture de l interface radlwsw_m.F90 entre LMDZ
    !                              et les codes radiatifs oldrad/rrtm/ecrad
    ! 
    !  lmdz_rad_out_m.F90 : calcul des flux radiatif pour les sorties LMDZ (commun aux 3 codes rad)
    ! --------------------------------------------------------------------------------------------------

    ! Modules necessaires
    USE DIMPHY
    USE yoethf_mod_h
    USE aero_mod
    USE conf_phys_m, ONLY: ok_ade, ok_aie, ok_volcan, iflag_rrtm
    USE wxios_mod, ONLY: missing_val
    ! ====================================================================

    ! ==============
    ! DECLARATIONS
    ! ==============

    ! Input arguments
    INTEGER,      INTENT(in) :: iof
    REAL(KIND=8), INTENT(in) :: PWV(kdlon,kflev)
    REAL(KIND=8), INTENT(in) :: ZFSUP(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFSDN(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFSUP0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFSDN0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFSUPC0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFSDNC0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFLUP(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFLDN(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFLUP0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFLDN0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFLUPC0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: ZFLDNC0(KDLON,KFLEV+1)
    REAL(KIND=8), INTENT(in) :: zheat(kdlon,kflev), zcool(kdlon,kflev)
    REAL(KIND=8), INTENT(in) :: zheat0(kdlon,kflev), zcool0(kdlon,kflev)
    REAL(KIND=8), INTENT(in) :: zheat_volc(kdlon,kflev), zcool_volc(kdlon,kflev) !NL
    REAL(KIND=8), INTENT(in) :: ztopsw(kdlon), ztoplw(kdlon)
    REAL(KIND=8), INTENT(in) :: zsolsw(kdlon), zsollw(kdlon), zalbpla(kdlon), zsolswfdiff(kdlon)
    REAL(KIND=8), INTENT(in) ::zsollwdown(kdlon)
    REAL(KIND=8), INTENT(in) :: ztopsw0(kdlon), ztoplw0(kdlon)
    REAL(KIND=8), INTENT(in) :: zsolsw0(kdlon), zsollw0(kdlon)
    REAL(KIND=8), INTENT(in) :: ztopswadaero(kdlon), zsolswadaero(kdlon)     ! Aerosol direct forcing at TOAand surface
    REAL(KIND=8), INTENT(in) :: ztopswad0aero(kdlon), zsolswad0aero(kdlon)   ! Aerosol direct forcing at TOAand surface
    REAL(KIND=8), INTENT(in) :: ztopswaiaero(kdlon), zsolswaiaero(kdlon)     ! dito, indirect
    REAL(KIND=8), INTENT(in) :: ztoplwadaero(kdlon), zsollwadaero(kdlon)     ! LW Aerosol direct forcing at TOAand surface
    REAL(KIND=8), INTENT(in) :: ztoplwad0aero(kdlon), zsollwad0aero(kdlon)   ! LW Aerosol direct forcing at TOAand surface
    REAL(KIND=8), INTENT(in) :: ztoplwaiaero(kdlon), zsollwaiaero(kdlon)     ! dito, indirect
    REAL(KIND=8), INTENT(in) :: ztopsw_aero(kdlon,9), ztopsw0_aero(kdlon,9)
    REAL(KIND=8), INTENT(in) :: zsolsw_aero(kdlon,9), zsolsw0_aero(kdlon,9)
    REAL(KIND=8), INTENT(in) :: ztopswcf_aero(kdlon,3), zsolswcf_aero(kdlon,3)

    ! Output arguments
    REAL,    INTENT(out) :: heat(KLON,KLEV), cool(KLON,KLEV)
    REAL,    INTENT(out) :: heat0(KLON,KLEV), cool0(KLON,KLEV)
    REAL,    INTENT(out) :: heat_volc(KLON,KLEV), cool_volc(KLON,KLEV) !NL
    REAL,    INTENT(out) :: topsw(KLON), toplw(KLON)
    REAL,    INTENT(out) :: solsw(KLON), sollw(KLON), solswfdiff(KLON)
    REAL,    INTENT(out) :: topsw0(KLON), toplw0(KLON), solsw0(KLON), sollw0(KLON)
    REAL,    INTENT(out) :: sollwdown(KLON)
    REAL,    INTENT(out) :: swdn(KLON,kflev+1),swdn0(KLON,kflev+1), swdnc0(KLON,kflev+1)
    REAL,    INTENT(out) :: swup(KLON,kflev+1),swup0(KLON,kflev+1), swupc0(KLON,kflev+1)
    REAL,    INTENT(out) :: lwdn(KLON,kflev+1),lwdn0(KLON,kflev+1), lwdnc0(KLON,kflev+1)
    REAL,    INTENT(out) :: lwup(KLON,kflev+1),lwup0(KLON,kflev+1), lwupc0(KLON,kflev+1)
    REAL,    INTENT(out) :: topswad_aero(KLON), solswad_aero(KLON)         ! output: aerosol direct forcing at TOA and surface
    REAL,    INTENT(out) :: topswai_aero(KLON), solswai_aero(KLON)         ! output: aerosol indirect forcing atTOA and surface
    REAL,    INTENT(out) :: toplwad_aero(KLON), sollwad_aero(KLON)         ! output: LW aerosol direct forcing at TOA and surface
    REAL,    INTENT(out) :: toplwai_aero(KLON), sollwai_aero(KLON)         ! output: LW aerosol indirect forcing atTOA and surface
    REAL, DIMENSION(klon), INTENT(out)    :: topswad0_aero 
    REAL, DIMENSION(klon), INTENT(out)    :: solswad0_aero
    REAL, DIMENSION(klon), INTENT(out)    :: toplwad0_aero 
    REAL, DIMENSION(klon), INTENT(out)    :: sollwad0_aero
    REAL, DIMENSION(kdlon,9), INTENT(out) :: topsw_aero
    REAL, DIMENSION(kdlon,9), INTENT(out) :: topsw0_aero
    REAL, DIMENSION(kdlon,9), INTENT(out) :: solsw_aero
    REAL, DIMENSION(kdlon,9), INTENT(out) :: solsw0_aero
    REAL, DIMENSION(kdlon,3), INTENT(out) :: topswcf_aero
    REAL, DIMENSION(kdlon,3), INTENT(out) :: solswcf_aero
    REAL,    INTENT(out) :: albpla(KLON)
    !Ecrad :
    REAL(KIND=8), INTENT(out) :: cloud_cover_sw(klon), &                   ! SW cloud cover issued from Rcrad
                                 ZFLUX_DIR(klon,klev+1), &              ! Direct compt of surf flux into horizontal plane
                                 ZFLUX_DIR_CLEAR(klon,klev+1), &        ! CS Direct
                                 ZFLUX_DIR_INTO_SUN(klon)

    ! Local variables
    INTEGER k, i
    REAL(KIND=8) zznormcp

     ! ----- flux radiatifs => sorties ---------------------------------  
       DO i = 1, kdlon
          topsw(iof+i) = ztopsw(i)
          toplw(iof+i) = ztoplw(i)
          solsw(iof+i) = zsolsw(i)
          solswfdiff(iof+i) = zsolswfdiff(i)
          sollw(iof+i) = zsollw(i)
          sollwdown(iof+i) = zsollwdown(i)
      ENDDO

      DO k = 1, kflev+1
         DO i = 1, kdlon
             lwdn0 ( iof+i,k)   = ZFLDN0 ( i,k)
             lwdn  ( iof+i,k)   = ZFLDN  ( i,k)
             lwup0 ( iof+i,k)   = ZFLUP0 ( i,k)
             lwup  ( iof+i,k)   = ZFLUP  ( i,k)
          ENDDO
      ENDDO

       DO i = 1, kdlon
          topsw0(iof+i) = ztopsw0(i)
          toplw0(iof+i) = ztoplw0(i)
          solsw0(iof+i) = zsolsw0(i)
          sollw0(iof+i) = zsollw0(i)
          albpla(iof+i) = zalbpla(i)
        ENDDO

        DO k = 1, kflev+1
          DO i = 1, kdlon
             swdnc0( iof+i,k)   = ZFSDNC0( i,k)
             swdn0 ( iof+i,k)   = ZFSDN0 ( i,k)
             swdn  ( iof+i,k)   = ZFSDN  ( i,k)
             swupc0( iof+i,k)   = ZFSUPC0( i,k)
             swup0 ( iof+i,k)   = ZFSUP0 ( i,k)
             swup  ( iof+i,k)   = ZFSUP  ( i,k)
             lwdnc0( iof+i,k)   = ZFLDNC0( i,k)
             lwupc0( iof+i,k)   = ZFLUPC0( i,k)
          ENDDO
       ENDDO
       !-transform the aerosol forcings, if they have
       ! to be calculated
       IF (ok_ade) THEN
          DO i = 1, kdlon
             topswad_aero(iof+i) = ztopswadaero(i)
             topswad0_aero(iof+i) = ztopswad0aero(i)
             solswad_aero(iof+i) = zsolswadaero(i)
             solswad0_aero(iof+i) = zsolswad0aero(i)
          ENDDO
          
             topsw_aero(:,:) = ztopsw_aero(:,:)
             topsw0_aero(:,:) = ztopsw0_aero(:,:)
             solsw_aero(:,:) = zsolsw_aero(:,:)
             solsw0_aero(:,:) = zsolsw0_aero(:,:)
             topswcf_aero(:,:) = ztopswcf_aero(:,:)
             solswcf_aero(:,:) = zsolswcf_aero(:,:)   
             !-LW
          DO i = 1, kdlon
             toplwad_aero(iof+i) = ztoplwadaero(i)
             toplwad0_aero(iof+i) = ztoplwad0aero(i)
             sollwad_aero(iof+i) = zsollwadaero(i)
             sollwad0_aero(iof+i) = zsollwad0aero(i)    
          ENDDO
       ELSE
          DO i = 1, kdlon
             topswad_aero(iof+i) = 0.0
             solswad_aero(iof+i) = 0.0
             topswad0_aero(iof+i) = 0.0
             solswad0_aero(iof+i) = 0.0
          ENDDO
             topsw_aero(:,:) = 0.
             topsw0_aero(:,:) =0.
             solsw_aero(:,:) = 0.
             solsw0_aero(:,:) = 0.
             !-LW
          DO i = 1, kdlon
             toplwad_aero(iof+i) = 0.0
             sollwad_aero(iof+i) = 0.0
             toplwad0_aero(iof+i) = 0.0
             sollwad0_aero(iof+i) = 0.0
          ENDDO
       ENDIF
       IF (ok_aie) THEN
          DO i = 1, kdlon
             topswai_aero(iof+i) = ztopswaiaero(i)
             solswai_aero(iof+i) = zsolswaiaero(i)
             !-LW
             toplwai_aero(iof+i) = ztoplwaiaero(i)
             sollwai_aero(iof+i) = zsollwaiaero(i)
          ENDDO
       ELSE
          DO i = 1, kdlon
             topswai_aero(iof+i) = 0.0
             solswai_aero(iof+i) = 0.0
             !-LW
             toplwai_aero(iof+i) = 0.0
             sollwai_aero(iof+i) = 0.0
          ENDDO
       ENDIF
       DO k = 1, kflev
          DO i = 1, kdlon
             !        scale factor to take into account the difference between
             !        dry air and watter vapour scpecifi! heat capacity
             zznormcp=1.0+RVTMP2*PWV(i,k)
             heat(iof+i,k) = zheat(i,k)/zznormcp
             cool(iof+i,k) = zcool(i,k)/zznormcp
             heat0(iof+i,k) = zheat0(i,k)/zznormcp
             cool0(iof+i,k) = zcool0(i,k)/zznormcp
             IF(ok_volcan) THEN !NL
                heat_volc(iof+i,k) = zheat_volc(i,k)/zznormcp
                cool_volc(iof+i,k) = zcool_volc(i,k)/zznormcp
             ENDIF
          ENDDO
       ENDDO
       IF (iflag_rrtm.ne.2) THEN
          cloud_cover_sw(:) = missing_val
          ZFLUX_DIR(:,:) = missing_val
          ZFLUX_DIR_CLEAR(:,:) = missing_val  
          ZFLUX_DIR_INTO_SUN = missing_val
       END IF

  END SUBROUTINE lmdz_rad_out
END MODULE lmdz_rad_out_m
