From 77465cf6a52224417f58d9a7646afc33b7c7dea4 Mon Sep 17 00:00:00 2001
From: Sibylle Techene <sibylle.techene@locean-ipsl.upmc.fr>
Date: Mon, 13 Jun 2022 14:56:29 +0000
Subject: [PATCH] Resolve "Fix restartability issues for RK3+ISF"

---
 src/OCE/ISF/isf_oce.F90 | 30 ++++++++++++++++++++++++------
 src/OCE/ISF/isfcav.F90  |  9 +++++++--
 src/OCE/ISF/isfhdiv.F90 | 29 ++++++++++++++++++++---------
 src/OCE/ISF/isfpar.F90  |  8 ++++++--
 src/OCE/ISF/isfstp.F90  |  6 ++++++
 src/OCE/TRA/traisf.F90  | 36 +++++++++++++++++++++++++++---------
 6 files changed, 90 insertions(+), 28 deletions(-)

diff --git a/src/OCE/ISF/isf_oce.F90 b/src/OCE/ISF/isf_oce.F90
index 16ff46027..eb62d83e9 100644
--- a/src/OCE/ISF/isf_oce.F90
+++ b/src/OCE/ISF/isf_oce.F90
@@ -80,8 +80,8 @@ MODULE isf_oce
    !
    ! 2.2 -------- ice shelf cavity melt namelist parameter -------------
    INTEGER  , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: mskisf_cav                    !:
-   INTEGER  , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: misfkt_cav   , misfkb_cav     !: 
-   REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: rhisf_tbl_cav, rfrac_tbl_cav  !: 
+   INTEGER  , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: misfkt_cav   , misfkb_cav     !: shallowest and deepest level of the ice shelf
+   REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: rhisf_tbl_cav, rfrac_tbl_cav  !: thickness and fraction of deepest cell affected by the ice shelf
    REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: fwfisf_cav   , fwfisf_cav_b   !: before and now net fwf from the ice shelf        [kg/m2/s]
    REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: risf_cav_tsc , risf_cav_tsc_b !: before and now T & S isf contents [K.m/s & PSU.m/s]  
    TYPE(FLD), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:)     :: sf_isfcav_fwf                 !:
@@ -237,17 +237,28 @@ CONTAINS
       !
       ierr = 0       ! set to zero if no array to be allocated
       !
-      ALLOCATE( fwfisf_par  (jpi,jpj) , fwfisf_par_b(jpi,jpj) ,     &
-         &      fwfisf_cav  (jpi,jpj) , fwfisf_cav_b(jpi,jpj) ,     &
+      ALLOCATE( fwfisf_par  (jpi,jpj) , fwfisf_cav  (jpi,jpj) ,     &
          &      fwfisf_oasis(jpi,jpj)                         , STAT=ialloc )
       ierr = ierr + ialloc
       !
-      ALLOCATE( risf_par_tsc(jpi,jpj,jpts) , risf_par_tsc_b(jpi,jpj,jpts) , STAT=ialloc )
+      ALLOCATE( risf_par_tsc(jpi,jpj,jpts) , STAT=ialloc )
       ierr = ierr + ialloc
       !
-      ALLOCATE( risf_cav_tsc(jpi,jpj,jpts) , risf_cav_tsc_b(jpi,jpj,jpts) , STAT=ialloc )
+      ALLOCATE( risf_cav_tsc(jpi,jpj,jpts) , STAT=ialloc )
       ierr = ierr + ialloc
       !
+#if ! defined key_RK3
+      ! MLF : need to allocate before arrays
+      ALLOCATE( fwfisf_par_b(jpi,jpj) , fwfisf_cav_b(jpi,jpj) , STAT=ialloc )
+      ierr = ierr + ialloc
+      !
+      ALLOCATE( risf_par_tsc_b(jpi,jpj,jpts) , STAT=ialloc )
+      ierr = ierr + ialloc
+      !
+      ALLOCATE( risf_cav_tsc_b(jpi,jpj,jpts) , STAT=ialloc )
+      ierr = ierr + ialloc
+#endif
+      !
       ALLOCATE( risfload(jpi,jpj) , STAT=ialloc )
       ierr = ierr + ialloc
       !
@@ -260,10 +271,17 @@ CONTAINS
       ! initalisation of fwf and tsc array to 0
       risfload    (:,:)   = 0._wp
       fwfisf_oasis(:,:)   = 0._wp
+#if defined key_RK3
+      fwfisf_par  (:,:)   = 0._wp
+      fwfisf_cav  (:,:)   = 0._wp
+      risf_cav_tsc(:,:,:) = 0._wp
+      risf_par_tsc(:,:,:) = 0._wp
+#else
       fwfisf_par  (:,:)   = 0._wp   ;   fwfisf_par_b  (:,:)   = 0._wp
       fwfisf_cav  (:,:)   = 0._wp   ;   fwfisf_cav_b  (:,:)   = 0._wp
       risf_cav_tsc(:,:,:) = 0._wp   ;   risf_cav_tsc_b(:,:,:) = 0._wp
       risf_par_tsc(:,:,:) = 0._wp   ;   risf_par_tsc_b(:,:,:) = 0._wp
+#endif
       !
    END SUBROUTINE isf_alloc
    
diff --git a/src/OCE/ISF/isfcav.F90 b/src/OCE/ISF/isfcav.F90
index 1a0597a83..27ca9912e 100644
--- a/src/OCE/ISF/isfcav.F90
+++ b/src/OCE/ISF/isfcav.F90
@@ -174,8 +174,10 @@ CONTAINS
       ! output fluxes
       CALL isf_diags_flx( Kmm, misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, 'cav', pqfwf, zqoce, zqlat, zqhc)
       !
-      ! write restart variables (qoceisf, qhcisf, fwfisf for now and before)
+#if ! defined key_RK3
+      ! MLF: write restart variables (qoceisf, qhcisf, fwfisf for now and before)
       IF (lrst_oce) CALL isfrst_write(kt, 'cav', ptsc, pqfwf)
+#endif
       !
       IF ( ln_isfdebug ) THEN
          IF(lwp) WRITE(numout,*) ''
@@ -215,6 +217,8 @@ CONTAINS
       !
       ! cavity mask
       mskisf_cav(:,:)    = (1._wp - tmask(:,:,1)) * ssmask(:,:)
+      !
+#if ! defined key_RK3
       !================
       ! 2: activate restart
       !================
@@ -223,9 +227,10 @@ CONTAINS
       ! 3: read restart
       !================
       !
-      ! read cav variable from restart
+      ! MLF: read cav variable from restart
       IF ( ln_rstart ) CALL isfrst_read('cav', risf_cav_tsc, fwfisf_cav, risf_cav_tsc_b, fwfisf_cav_b)
       !
+#endif
       !==========================================
       ! 3: specific allocation and initialisation (depending of scheme choice)
       !==========================================
diff --git a/src/OCE/ISF/isfhdiv.F90 b/src/OCE/ISF/isfhdiv.F90
index 772ab9a74..58275063b 100644
--- a/src/OCE/ISF/isfhdiv.F90
+++ b/src/OCE/ISF/isfhdiv.F90
@@ -5,6 +5,7 @@ MODULE isfhdiv
    !!                   with the ice shelf melt and coupling correction
    !!======================================================================
    !! History :  4.0  !  2019-09  (P. Mathiot) Original code
+   !!            4.2  !  2022-05  (S. Techene) Update wrt RK3 time-stepping
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -45,11 +46,19 @@ CONTAINS
       !
       IF ( ln_isf ) THEN
          !
-         ! ice shelf cavity contribution
-         IF ( ln_isfcav_mlt ) CALL isf_hdiv_mlt(misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, fwfisf_cav, fwfisf_cav_b, phdiv)
+#if defined key_RK3
+         ! ice shelf cavity contribution (RK3)
+         IF ( ln_isfcav_mlt ) CALL isf_hdiv_mlt(misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, fwfisf_cav, phdiv)
+         !
+         ! ice shelf parametrisation contribution (RK3)
+         IF ( ln_isfpar_mlt ) CALL isf_hdiv_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, fwfisf_par, phdiv)
+#else
+         ! ice shelf cavity contribution (MLF)
+         IF ( ln_isfcav_mlt ) CALL isf_hdiv_mlt(misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, fwfisf_cav, phdiv, fwfisf_cav_b)
          !
-         ! ice shelf parametrisation contribution
-         IF ( ln_isfpar_mlt ) CALL isf_hdiv_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, fwfisf_par, fwfisf_par_b, phdiv)
+         ! ice shelf parametrisation contribution (MLF)
+         IF ( ln_isfpar_mlt ) CALL isf_hdiv_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, fwfisf_par, phdiv, fwfisf_par_b)
+#endif
          !
          ! ice sheet coupling contribution
          IF ( ln_isfcpl .AND. kt /= 0 ) THEN
@@ -72,7 +81,7 @@ CONTAINS
    END SUBROUTINE isf_hdiv
 
 
-   SUBROUTINE isf_hdiv_mlt(ktop, kbot, phtbl, pfrac, pfwf, pfwf_b, phdiv)
+   SUBROUTINE isf_hdiv_mlt(ktop, kbot, phtbl, pfrac, pfwf, phdiv, pfwf_b)
       !!----------------------------------------------------------------------
       !!                  ***  SUBROUTINE sbc_isf_div  ***
       !!       
@@ -83,11 +92,12 @@ CONTAINS
       !!
       !! ** Action  :   phdivn   increased by the ice shelf outflow
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) :: phdiv
+      REAL(wp), DIMENSION(jpi,jpj,jpk)      , INTENT(inout) :: phdiv
       !!----------------------------------------------------------------------
-      INTEGER , DIMENSION(jpi,jpj), INTENT(in   ) :: ktop , kbot
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) :: pfrac, phtbl
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) :: pfwf , pfwf_b
+      INTEGER , DIMENSION(jpi,jpj)          , INTENT(in   ) :: ktop , kbot
+      REAL(wp), DIMENSION(jpi,jpj)          , INTENT(in   ) :: pfrac, phtbl
+      REAL(wp), DIMENSION(jpi,jpj)          , INTENT(in   ) :: pfwf
+      REAL(wp), DIMENSION(:,:)    , OPTIONAL, INTENT(in   ) :: pfwf_b
       !!----------------------------------------------------------------------
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       INTEGER  ::   ikt, ikb 
@@ -119,6 +129,7 @@ CONTAINS
       !
    END SUBROUTINE isf_hdiv_mlt
 
+
    SUBROUTINE isf_hdiv_cpl(Kmm, pqvol, phdiv)
       !!----------------------------------------------------------------------
       !!                  ***  SUBROUTINE isf_hdiv_cpl  ***
diff --git a/src/OCE/ISF/isfpar.F90 b/src/OCE/ISF/isfpar.F90
index 3dae222da..31f363687 100644
--- a/src/OCE/ISF/isfpar.F90
+++ b/src/OCE/ISF/isfpar.F90
@@ -93,9 +93,11 @@ CONTAINS
       ! output fluxes
       CALL isf_diags_flx( Kmm, misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, 'par', pqfwf, zqoce, zqlat, zqhc)
       !
-      ! write restart variables (qoceisf, qhcisf, fwfisf for now and before)
+#if ! defined key_RK3
+      ! MLF: write restart variables (qoceisf, qhcisf, fwfisf for now and before)
       IF (lrst_oce) CALL isfrst_write(kt, 'par', ptsc, pqfwf)
       !
+#endif
       IF ( ln_isfdebug ) THEN
          IF(lwp) WRITE(numout,*)
          CALL debug('isf_par: ptsc T',ptsc(:,:,1))
@@ -155,8 +157,10 @@ CONTAINS
          mskisf_par(:,:) = 1._wp
       END WHERE
       !
-      ! read par variable from restart
+#if ! defined key_RK3
+      ! MLF: read par variable from restart
       IF ( ln_rstart ) CALL isfrst_read('par', risf_par_tsc, fwfisf_par, risf_par_tsc_b, fwfisf_par_b)
+#endif
       !
       SELECT CASE ( TRIM(cn_isfpar_mlt) )
          !
diff --git a/src/OCE/ISF/isfstp.F90 b/src/OCE/ISF/isfstp.F90
index cef91bb94..edc5f92aa 100644
--- a/src/OCE/ISF/isfstp.F90
+++ b/src/OCE/ISF/isfstp.F90
@@ -74,11 +74,14 @@ CONTAINS
       !
       IF ( ln_isfcav_mlt ) THEN
          !
+#if ! defined key_RK3
+         ! MLF : need risf_cav_tsc_b update
          ! 1.1: before time step 
          IF ( kt /= nit000 ) THEN 
             risf_cav_tsc_b (:,:,:) = risf_cav_tsc (:,:,:)
             fwfisf_cav_b(:,:)      = fwfisf_cav(:,:)
          END IF
+#endif
          !
          ! 1.2: compute misfkb, rhisf_tbl, rfrac (deepest level, thickness, fraction of deepest cell affected by tbl)
          rhisf_tbl_cav(:,:) = rn_htbl * mskisf_cav(:,:)
@@ -102,11 +105,14 @@ CONTAINS
       !
       IF ( ln_isfpar_mlt ) THEN
          !
+#if ! defined key_RK3
+         ! MLF : need risf_par_tsc_b update
          ! 2.1: before time step 
          IF ( kt /= nit000 ) THEN 
             risf_par_tsc_b(:,:,:) = risf_par_tsc(:,:,:)
             fwfisf_par_b  (:,:)   = fwfisf_par  (:,:)
          END IF
+#endif
          !
          ! 2.2: compute misfkb, rhisf_tbl, rfrac (deepest level, thickness, fraction of deepest cell affected by tbl)
          ! by simplicity, we assume the top level where param applied do not change with time (done in init part)
diff --git a/src/OCE/TRA/traisf.F90 b/src/OCE/TRA/traisf.F90
index 7f43285b9..610f9064f 100644
--- a/src/OCE/TRA/traisf.F90
+++ b/src/OCE/TRA/traisf.F90
@@ -17,6 +17,8 @@ MODULE traisf
    USE isfutils, ONLY : debug                      ! debug option
    USE timing  , ONLY : timing_start, timing_stop  ! Timing
    USE in_out_manager                              ! I/O manager
+   !
+   USE prtctl                                      ! print control
 
    IMPLICIT NONE
    PRIVATE
@@ -56,11 +58,19 @@ CONTAINS
          ENDIF
       ENDIF
       !
-      ! cavity case
-      IF ( ln_isfcav_mlt ) CALL isf_mlt(misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, risf_cav_tsc, risf_cav_tsc_b, pts(:,:,:,:,Krhs))
+#if defined key_RK3
+      ! cavity case (RK3)
+      IF ( ln_isfcav_mlt ) CALL isf_mlt(misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, risf_cav_tsc, pts(:,:,:,:,Krhs))
       !
-      ! parametrisation case
-      IF ( ln_isfpar_mlt ) CALL isf_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, risf_par_tsc, risf_par_tsc_b, pts(:,:,:,:,Krhs))
+      ! parametrisation case (RK3)
+      IF ( ln_isfpar_mlt ) CALL isf_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, risf_par_tsc, pts(:,:,:,:,Krhs))
+#else
+      ! cavity case (MLF)
+      IF ( ln_isfcav_mlt ) CALL isf_mlt(misfkt_cav, misfkb_cav, rhisf_tbl_cav, rfrac_tbl_cav, risf_cav_tsc, pts(:,:,:,:,Krhs), risf_cav_tsc_b)
+      !
+      ! parametrisation case (MLF)
+      IF ( ln_isfpar_mlt ) CALL isf_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, risf_par_tsc, pts(:,:,:,:,Krhs), risf_par_tsc_b)
+#endif
       !
       ! ice sheet coupling case
       IF ( ln_isfcpl ) THEN
@@ -86,12 +96,15 @@ CONTAINS
          ENDIF
       END IF
       !
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' isf  - Ta: ', mask1=tmask,   &
+         &                                  tab3d_2=pts(:,:,:,jp_sal,Krhs), clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
+      !
       IF( ln_timing )   CALL timing_stop('tra_isf')
       !
    END SUBROUTINE tra_isf
 
    
-   SUBROUTINE isf_mlt( ktop, kbot, phtbl, pfrac, ptsc, ptsc_b, pts )
+   SUBROUTINE isf_mlt( ktop, kbot, phtbl, pfrac, ptsc, pts, ptsc_b )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE isf_mlt  ***
       !!
@@ -100,10 +113,11 @@ CONTAINS
       !! *** Action :: Update pts(:,:,:,:,Krhs) with the surface boundary condition trend
       !!
       !!----------------------------------------------------------------------
-      INTEGER , DIMENSION(jpi,jpj)         , INTENT(in   ) ::   ktop , kbot
-      REAL(wp), DIMENSION(jpi,jpj)         , INTENT(in   ) ::   phtbl, pfrac
-      REAL(wp), DIMENSION(jpi,jpj,jpts)    , INTENT(in   ) ::   ptsc , ptsc_b
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(inout) ::   pts
+      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts)          , INTENT(inout) ::   pts
+      INTEGER , DIMENSION(jpi,jpj)                   , INTENT(in   ) ::   ktop , kbot
+      REAL(wp), DIMENSION(jpi,jpj)                   , INTENT(in   ) ::   phtbl, pfrac
+      REAL(wp), DIMENSION(jpi,jpj,jpts)              , INTENT(in   ) ::   ptsc
+      REAL(wp), DIMENSION(:,:,:)           , OPTIONAL, INTENT(in   ) ::   ptsc_b
       !!
       INTEGER ::   ji,jj,jk   ! dummy loop index
       INTEGER ::   ikt, ikb   ! top and bottom level of the tbl
@@ -112,7 +126,11 @@ CONTAINS
       !
       ! compute 2d total trend due to isf
       DO_2D( 0, 0, 0, 0 )
+#if defined key_RK3
+         ztc(ji,jj) = ptsc(ji,jj,jp_tem) / phtbl(ji,jj)
+#else
          ztc(ji,jj) = 0.5_wp * ( ptsc(ji,jj,jp_tem) + ptsc_b(ji,jj,jp_tem) ) / phtbl(ji,jj)
+#endif
       END_2D
       !
       ! update pts(:,:,:,:,Krhs)
-- 
GitLab