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.
#2487 (Inflexible calendar year and approximate conversion in option 2 of the freshwater-budget adjustment mechanism) – NEMO

Opened 4 years ago

Last modified 2 years ago

#2487 assigned Defect

Inflexible calendar year and approximate conversion in option 2 of the freshwater-budget adjustment mechanism

Reported by: smueller Owned by: smueller
Priority: low Milestone:
Component: SBC Version: v4.0.*
Severity: minor Keywords: fwb, SBC
Cc:

Description

Context

Option 2 of the freshwater-budget adjustment mechanism (nn_fwb = 2, module sbcfwb) uses a fixed calendar year of 365 days rather than that of the selected model calendar to time annual updates of the adjustment flux; this issue has previously been reported in the form of source-code comments (source:/NEMO/releases/r4.0/r4.0-HEAD/src/OCE/SBC/sbcfwb.F90@12578#L129 and source:/NEMO/releases/r4.0/r4.0-HEAD/src/OCE/SBC/sbcfwb.F90@12578#L135). Further, the conversion of the combined sea-level, sea-ice, and snow anomaly into an equivalent freshwater flux is approximate and not in line with corresponding conversions used elsewhere in the model.

Analysis

In option 2 of the freshwater-budget adjustment mechanism, year boundaries are identified whenever the reminder of the division of the time step counter by 365 * 86400 / rdt equals zero (source:/NEMO/releases/r4.0/r4.0-HEAD/src/OCE/SBC/sbcfwb.F90@12578#L130). This i) fixes the adjustment interval to 365 days, ii) sets the date for annual adjustment-flux updates to the date of nit000 - 1 rather than the start of 1 January, and iii) leads to an update of the adjustment flux near the start of the final time step of each year (i.e., before completion of that model year).

Line source:/NEMO/releases/r4.0/r4.0-HEAD/src/OCE/SBC/sbcfwb.F90@12578#L134 implements the conversion of a combined sea-level, sea ice, and snow anomaly into an equivalent annual-average freshwater flux using a literal value of 1000.0 for the density of sea water and 365 for the number of days in a year rather than variables rau0 and nyear_len(1), respectively.

The impact of these approximations can be demonstrated using reference configuration GYRE_PISCES (which uses calendar years of 360 days) after replacing source:/NEMO/releases/r4.0/r4.0-HEAD/src/OCE/USR/usrdef_sbc.F90@12578#L134 by zsumemp = 0.0_wp and activation of the freshwater-budget adjustment by setting namelist parameter nn_fwb = 2.

Recommendation

The annual average freshwater adjustment based on the sea-level and sea-ice anomaly at the end of the preceding model year should be computed using daymod variable nyear_len (i.e., the calendar year during which the adjustment will be applied) and using the reference sea-water density rau0 rather than the literal values 365 and 1000.0, respectively. Further, it would be useful for interpretability of the effect of the freshwater-adjustment mechanism to exactly align the annual computation of the freshwater-budget adjustment with the model calendar. Therefore, adjustment-flux updates could occur in the first time step of each new year, which should be identified using variables updated by module daymod such as through the conditional ( ( nday_year == 1 ) .AND. ( nsec_day == NINT( 0.5_wp * rdt ) ) ).

Commit History (15)

ChangesetAuthorTimeChangeLog
15451clem2021-10-27T16:46:28+02:00

4.0-HEAD only: change vertical scale factors for embedded sea ice as proposed in ticket #2487.

15439clem2021-10-22T19:53:09+02:00

trunk: freshwater budget is now corrected for option nn_fwb=2. The option could be improved. There is a drift the 1st year and the correction applied can lead to oscillations in the solution. It is related to tickets #2718 and part of #2487 though the fix is somewhat different than proposed in the tickets.

15438clem2021-10-22T16:56:07+02:00

4.0-HEAD: freshwater budget is now corrected for option nn_fwb=2. The option could be improved. There is a drift the 1st year and the correction applied can lead to oscillations in the solution. It is related to tickets #2718 and part of #2487 though the fix is somewhat different than proposed in the tickets.

15418smueller2021-10-20T16:53:18+02:00

Addition of vertical-scale-factor and water-column-height updates to complete initial SSH adjustments due to non-zero sea-ice/snow mass (ticket #2487)

15414smueller2021-10-20T13:13:14+02:00

Transfer of a reusable section of subroutine dom_vvl_init into the new module subroutine dom_vvl_zgr (backport from trunk, ticket #2487)

15410smueller2021-10-20T11:10:59+02:00

Synchronizing with /NEMO/releases/r4.0/r4.0-HEAD@15405 (ticket #2487)

15264smueller2021-09-16T12:42:20+02:00

Synchronizing with /NEMO/releases/r4.0/r4.0-HEAD@15236 (ticket #2487)

13301smueller2020-07-13T16:12:27+02:00

Addition of warning output from model runs with sea ice, with active freshwater-budget adjustment, but without sea-level compensation for non-zero initial sea-ice/snow mass (see ticket #2487)

13300smueller2020-07-13T15:06:28+02:00

Activation of sea-level compensation for non-zero initial sea-ice/snow mass in reference configuration ORCA2_ICE_PISCES (see ticket #2487)

13299smueller2020-07-13T14:34:12+02:00

Addition of a namelist parameter to enable the selectability of sea-level compensation for non-zero sea-ice/snow mass (see ticket #2487)

13294smueller2020-07-10T20:15:20+02:00

Overriding of the initial sea-level compensation for non-zero sea-ice/snow mass in nested domains (see ticket #2487)

13180smueller2020-06-29T21:31:19+02:00

Inclusion of ice-shelf cavities in the sea-level compensation due to initial sea-ice/snow mass and in the freshwater-budget adjustment (see ticket #2487)

13179smueller2020-06-29T20:04:05+02:00

Addition of initial sea-level compensation for non-zero sea-ice/snow mass (see ticket #2487)

13177smueller2020-06-29T18:50:21+02:00

Replacement of hard-coded constants with model variables and modification of the adjustment-update synchronization in option 2 of the freshwater-budget adjustment mechanism (see ticket #2487)

13171smueller2020-06-29T12:05:58+02:00

Inception of a branch associated with ticket #2487

Change History (25)

comment:1 Changed 4 years ago by smueller

In order to implement the recommendation above, source:/NEMO/releases/r4.0/r4.0-HEAD/src/OCE/SBC/sbcfwb.F90@13098 could be modified according to:

  • src/OCE/SBC/sbcfwb.F90

     
    124124            IF(lwp)WRITE(numout,*)'sbc_fwb : year = ',iyear  , ' freshwater budget correction = ', fwfold 
    125125            IF(lwp)WRITE(numout,*)'          year = ',iyear-1, ' freshwater budget read       = ', a_fwb 
    126126            IF(lwp)WRITE(numout,*)'          year = ',iyear-2, ' freshwater budget read       = ', a_fwb_b 
    127          ENDIF    
    128          !                                         ! Update fwfold if new year start 
    129          ikty = 365 * 86400 / rdt                  !!bug  use of 365 days leap year or 360d year !!!!!!! 
    130          IF( MOD( kt, ikty ) == 0 ) THEN 
     127         ELSEIF( ( nday_year == 1 ) .AND. ( nsec_day == NINT( 0.5_wp * rdt ) ) ) THEN   ! Update fwfold at the start of 1 January 
    131128            a_fwb_b = a_fwb                           ! mean sea level taking into account the ice+snow 
    132129                                                      ! sum over the global domain 
    133130            a_fwb   = glob_sum( 'sbcfwb', e1e2t(:,:) * ( sshn(:,:) + snwice_mass(:,:) * r1_rau0 ) ) 
    134             a_fwb   = a_fwb * 1.e+3 / ( area * rday * 365. )     ! convert in Kg/m3/s = mm/s 
    135 !!gm        !                                                      !!bug 365d year  
     131            a_fwb   = a_fwb * rau0 / ( area * rday * nyear_len(1) )     ! convert into kg/m3/s 
    136132            fwfold =  a_fwb                           ! current year freshwater budget correction 
    137133            !                                         ! estimate from the previous year budget 
    138134         ENDIF 

comment:2 Changed 4 years ago by smueller

In a discussion with Gurvan and Seb, Gurvan pointed out two further bugs related to this defect:

i) in contrast to model configurations with embedded sea-ice, in the presence of levitating sea-ice/snow (ln_ice_embd = .FALSE., default case) the initial sea-level is not adjusted to compensate for the initial combined sea-ice and snow mass (missing adjustment of initial sshn and sshb values by the global average of the initial snwice_mass field converted to an equivalent sea-level anomaly during initialisation of both SI3 and the CICE coupling interface), which leads to a non-zero global-average sea-level anomaly for an ice/snow-less ocean with identical total mass of water, and, when nn_fwb = 2 to an extra freshwater adjustment fluxes early in the simulation; and

ii) the freshwater-budget adjustment computation does not take into account under-ice-shelf areas (if any) as the computation of the surface area masks the grid-cell areas by tmask(:,:,1), instead of by ssmask(:,:) only (as applied in function glob_sum).

These two bugs could be fixed by making the modifications

  • src/ICE/iceistate.F90

     
    9191      INTEGER, INTENT(in) ::   kt   ! time step  
    9292      !! 
    9393      INTEGER  ::   ji, jj, jk, jl         ! dummy loop indices 
    94       REAL(wp) ::   ztmelts 
     94      REAL(wp) ::   ztmelts, z1_area, zsshadj 
    9595      INTEGER , DIMENSION(4)           ::   itest 
    9696      REAL(wp), DIMENSION(jpi,jpj)     ::   z2d 
    9797      REAL(wp), DIMENSION(jpi,jpj)     ::   zswitch    ! ice indicator 
     
    424424               gde3w_n(:,:,jk) = gdept_n(:,:,jk  ) - sshn (:,:) 
    425425            END DO 
    426426         ENDIF 
     427      ELSE 
     428         z1_area = 1.0_wp / glob_sum( 'iceistate', e1e2t(:,:) ) 
     429         zsshadj = glob_sum( 'iceistate', e1e2t(:,:) * snwice_mass(:,:) ) * r1_rau0 * z1_area 
     430         WRITE(ctmp1,'(A34,F10.6,A32)') 'iceistate:   mean ssh adjusted by ', -1.0_wp * zsshadj, ' m to compensate for the initial' 
     431         CALL ctl_warn( ctmp1,          '             ice+snow mass' ) 
     432         sshn(:,:) = sshn(:,:) - zsshadj 
     433         sshb(:,:) = sshb(:,:) - zsshadj 
    427434      ENDIF 
    428435       
    429436      !------------------------------------ 
  • src/OCE/SBC/sbcice_cice.F90

     
    154154      !!--------------------------------------------------------------------- 
    155155      INTEGER, INTENT( in  ) ::   ksbc                ! surface forcing type 
    156156      REAL(wp), DIMENSION(jpi,jpj) :: ztmp1, ztmp2 
    157       REAL(wp) ::   zcoefu, zcoefv, zcoeff            ! local scalar 
     157      REAL(wp) ::   zcoefu, zcoefv, zcoeff            ! local scalars 
     158      REAL(wp) ::   z1_area, zsshadj                  !   "      " 
    158159      INTEGER  ::   ji, jj, jl, jk                    ! dummy loop indices 
    159160      !!--------------------------------------------------------------------- 
    160161      ! 
     
    265266                  gde3w_n(:,:,jk) = gdept_n(:,:,jk  ) - sshn   (:,:) 
    266267               END DO 
    267268            ENDIF 
     269         ELSE 
     270            z1_area = 1.0_wp / glob_sum( 'sbcice_cice', e1e2t(:,:) ) 
     271            zsshadj = glob_sum( 'sbcice_cice', e1e2t(:,:) * snwice_mass(:,:) ) * r1_rau0 * z1_area 
     272            WRITE(ctmp1,'(A38,F10.6,A24)') 'sbcicce_cice:   mean ssh adjusted by ', -1.0_wp * zsshadj, ' m to compensate for the' 
     273            CALL ctl_warn( ctmp1,          '                initial ice+snow mass' ) 
     274            sshn(:,:) = sshn(:,:) - zsshadj 
     275            sshb(:,:) = sshb(:,:) - zsshadj 
    268276         ENDIF 
    269277      ENDIF 
    270278      ! 

and

  • src/OCE/SBC/sbcfwb.F90

     
    3737   REAL(wp) ::   a_fwb     ! for 2 year before (_b) and before year. 
    3838   REAL(wp) ::   fwfold    ! fwfold to be suppressed 
    3939   REAL(wp) ::   area      ! global mean ocean surface (interior domain) 
     40   REAL(wp) ::   area2     ! global ocean surface area (interior domain) incl. ice-shelf cavities 
    4041 
    4142   !! * Substitutions 
    4243#  include "vectopt_loop_substitute.h90" 
     
    9091         area = glob_sum( 'sbcfwb', e1e2t(:,:) * tmask(:,:,1))           ! interior global domain surface 
    9192         ! isf cavities are excluded because it can feedback to the melting with generation of inhibition of plumes 
    9293         ! and in case of no melt, it can generate HSSW. 
     94         area2 = glob_sum( 'sbcfwb', e1e2t(:,:) )                        ! global interior-domain ocean surface incl. ice-shelf cavities 
    9395         ! 
    9496#if ! defined key_si3 && ! defined key_cice 
    9597         snwice_mass_b(:,:) = 0.e0               ! no sea-ice model is being used : no snow+ice mass 
     
    131133            a_fwb_b = a_fwb                           ! mean sea level taking into account the ice+snow 
    132134                                                      ! sum over the global domain 
    133135            a_fwb   = glob_sum( 'sbcfwb', e1e2t(:,:) * ( sshn(:,:) + snwice_mass(:,:) * r1_rau0 ) ) 
    134             a_fwb   = a_fwb * 1.e+3 / ( area * rday * 365. )     ! convert in Kg/m3/s = mm/s 
     136            a_fwb   = a_fwb * 1.e+3 / ( area2 * rday * 365. )     ! convert in Kg/m3/s = mm/s 
    135137!!gm        !                                                      !!bug 365d year  
    136138            fwfold =  a_fwb                           ! current year freshwater budget correction 
    137139            !                                         ! estimate from the previous year budget 
Last edited 4 years ago by smueller (previous) (diff)

comment:3 Changed 4 years ago by smueller

In 13171:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:4 Changed 4 years ago by smueller

Gurvan pointed out another bug related to those described in comment:2: in the presence of embedded sea ice (ln_ice_embd = .TRUE.), the adjustment of the vertical scale factors e3t_n and e3t_b following the sea-level adjustment due to the initial sea-ice/snow mass in both SI3 and the CICE coupling interface ignores under-ice-shelf areas (if any). He recommends to make the modifications

  • src/ICE/iceistate.F90

     
    387387         ! 
    388388         IF( .NOT.ln_linssh ) THEN 
    389389            ! 
    390             WHERE( ht_0(:,:) > 0 )   ;   z2d(:,:) = 1._wp + sshn(:,:)*tmask(:,:,1) / ht_0(:,:) 
    391             ELSEWHERE                ;   z2d(:,:) = 1._wp   ;   END WHERE 
     390            z2d(:,:) = 1._wp + sshn(:,:) * ssmask(:,:) / ( ht_0(:,:) + 1._wp - ssmask(:,:) ) 
    392391            ! 
    393392            DO jk = 1,jpkm1                     ! adjust initial vertical scale factors                 
    394393               e3t_n(:,:,jk) = e3t_0(:,:,jk) * z2d(:,:) 

and

  • src/OCE/SBC/sbcice_cice.F90

     
    234234            IF( .NOT.ln_linssh ) THEN 
    235235               ! 
    236236               DO jk = 1,jpkm1                     ! adjust initial vertical scale factors 
    237                   e3t_n(:,:,jk) = e3t_0(:,:,jk)*( 1._wp + sshn(:,:)*tmask(:,:,1)/(ht_0(:,:) + 1.0 - tmask(:,:,1)) ) 
    238                   e3t_b(:,:,jk) = e3t_0(:,:,jk)*( 1._wp + sshb(:,:)*tmask(:,:,1)/(ht_0(:,:) + 1.0 - tmask(:,:,1)) ) 
     237                  e3t_n(:,:,jk) = e3t_0(:,:,jk)*( 1._wp + sshn(:,:)*ssmask(:,:)/(ht_0(:,:) + 1._wp - ssmask(:,:)) ) 
     238                  e3t_b(:,:,jk) = e3t_0(:,:,jk)*( 1._wp + sshb(:,:)*ssmask(:,:)/(ht_0(:,:) + 1._wp - ssmask(:,:)) ) 
    239239               ENDDO 
    240240               e3t_a(:,:,:) = e3t_b(:,:,:) 
    241241               ! Reconstruction of all vertical scale factors at now and before time-steps 
Last edited 4 years ago by smueller (previous) (diff)

comment:5 Changed 4 years ago by smueller

In 13177:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:6 Changed 4 years ago by smueller

In 13179:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:7 Changed 4 years ago by smueller

In 13180:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:8 Changed 4 years ago by smueller

Using source:/NEMO/branches/2020/ticket2487@13180, runs of the model in the AGRIF_DEMO reference configuration terminate with an error during time step 59 of the nested domain 2.

A possible reason for this error could be the substantial differences between the initial sea-level adjustments made in the different domains (about -0.125 m in the global domain, 0.0 m in nested domain 1, about -0.881 m in nested domain 2, and about -1.491 in nested domain 3). For consistency, the initial sea-levels of all domains should be adjusted by the same amount.

comment:9 Changed 4 years ago by smueller

In 13294:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:10 Changed 4 years ago by smueller

source:/NEMO/branches/2020/ticket2487@13294 passes the AGRIF_DEMO SETTE tests.

In order to reduce the number of reference configurations that are affected by the addition of the sea-level adjustment due to initial sea-ice and snow mass, the sea-level adjustment could be made conditional on a new namelist parameter and be activated in reference configurations with activated freshwater adjustment only (nn_fwb > 0; currently ORCA2_ICE_PISCES).

comment:11 Changed 4 years ago by smueller

In 13299:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:12 Changed 4 years ago by smueller

In 13300:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:13 Changed 4 years ago by smueller

In 13301:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:14 Changed 3 years ago by smueller

  • Owner changed from systeam to smueller
  • Status changed from new to assigned
  • Version v4.0.* deleted

comment:15 Changed 3 years ago by smueller

  • Version set to v4.0

comment:16 Changed 3 years ago by nemo

  • Version changed from v4.0 to v4.0.*

comment:17 Changed 3 years ago by smueller

In 15264:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:18 Changed 3 years ago by smueller

In 15410:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:19 Changed 3 years ago by smueller

In 15414:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:20 Changed 3 years ago by smueller

In 15418:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:21 Changed 3 years ago by smueller

source:/NEMO/branches/2020/ticket2487@15418 has passed the standard SETTE tests of reference configuration ORCA2_ICE_PISCES.

comment:22 Changed 3 years ago by clem

In 15438:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:23 Changed 3 years ago by clem

In 15439:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found

comment:24 Changed 2 years ago by smueller

  • branch_review changed from failed to pending

comment:25 Changed 2 years ago by clem

In 15451:

Error: Failed to load processor CommitTicketReference
No macro or processor named 'CommitTicketReference' found
Note: See TracTickets for help on using tickets.