Opened 3 months ago

Last modified 3 months ago

#2509 new Defect

AGRIF_DEMO: strange salinity in parent grid close to the coast if ln_linssh=F

Reported by: andrea.gierisch Owned by: systeam
Priority: low Milestone:
Component: AGRIF Version: release-4.0
Severity: minor Keywords: AGRIF, release-4.0.2, AGRIF_DEMO
Cc: andrea.gierisch

Description

Context

I'm running AGRIF_DEMO with release-4.0.2. The salinity in the first nest (2_Nordic) looks weird around the coast in those areas, which are covered by the second nest (3_Nordic). The values in 3_Nordic however look fine. The effect disappears if I set ln_linssh=T for all nests.

I use:
Code and namelists etc.:
https://forge.ipsl.jussieu.fr/nemo/svn/NEMO/releases/r4.0/r4.0.2 revision r13375
Input data:
https://zenodo.org/record/1472245/files/AGRIF_DEMO_v4.0.tar?download=1
https://zenodo.org/record/1472245/files/ORCA2_ICE_v4.0.tar?download=1

Output frequency set to 1-daily.

Analysis

The effect happens for those ocean grid cells in the parent grid whose corresponding child-grid cells are mostly covered by land. The salinity at these parent grid cells is unexpectedly high if the sea level (zos) is <0 and unexpectedly low if zos>0. As zos is connected to e3t if ln_linssh=F, I suspect that AGRIF does something wrong when updating the salinity from the child to the parent. Maybe e3t is not taken into account correctly? It's too fresh when the cells are thick and too salty when the cells are shallow.

This effect is more pronounced in my own setup (a nest around Greenland from an Arctic setup - I'll attach some plots) but as it is also visible in AGRIF_DEMO, I think it could be a general problem and not only related to deficiencies in my own setup…?

Recommendation

Work-around: set ln_linssh=T, but this is not really a solution…
I'd be happy if someone has a better idea how to fix this.

Commit History (0)

(No commits)

Attachments (8)

AGRIFDEMO_so_parent.png (15.7 KB) - added by andrea.gierisch 3 months ago.
AGRIF_DEMO: Salinity in parent grid (2_Nordic) at level 1 on day 5
AGRIFDEMO_so_nest.png (32.3 KB) - added by andrea.gierisch 3 months ago.
AGRIF_DEMO: Salinity in nest (3_Nordic) at level 1 on day 5
AGRIFDEMO-with-linSSH_so_parent.png (15.5 KB) - added by andrea.gierisch 3 months ago.
AGRIF_DEMO: Salinity in parent grid (2_Nordic) at level 1 on day 5, if ln_linssh=T
AGRIFDEMO_e3t_parent.png (29.8 KB) - added by andrea.gierisch 3 months ago.
AGRIF_DEMO: e3t in parent grid (2_Nordic) at level 1 on day 5
GREENLAND_so_parent.png (22.8 KB) - added by andrea.gierisch 3 months ago.
GREENLAND: Salinity in parent grid at level 1 after 2 hours
GREENLAND_so_nest.png (48.0 KB) - added by andrea.gierisch 3 months ago.
GREENLAND: Salinity in nest grid at level 1 after 2 hours
GREENLAND_zos_nest.png (33.8 KB) - added by andrea.gierisch 3 months ago.
GREENLAND: zos in nest grid after 2 hours
GREENLAND_so_parent_new.png (14.9 KB) - added by andrea.gierisch 3 months ago.
AGRIF_DEMO: Salinity in parent after removing e3t in the code

Download all attachments as: .zip

Change History (10)

Changed 3 months ago by andrea.gierisch

AGRIF_DEMO: Salinity in parent grid (2_Nordic) at level 1 on day 5

Changed 3 months ago by andrea.gierisch

AGRIF_DEMO: Salinity in nest (3_Nordic) at level 1 on day 5

Changed 3 months ago by andrea.gierisch

AGRIF_DEMO: Salinity in parent grid (2_Nordic) at level 1 on day 5, if ln_linssh=T

Changed 3 months ago by andrea.gierisch

AGRIF_DEMO: e3t in parent grid (2_Nordic) at level 1 on day 5

Changed 3 months ago by andrea.gierisch

GREENLAND: Salinity in parent grid at level 1 after 2 hours

Changed 3 months ago by andrea.gierisch

GREENLAND: Salinity in nest grid at level 1 after 2 hours

Changed 3 months ago by andrea.gierisch

GREENLAND: zos in nest grid after 2 hours

comment:1 follow-up: Changed 3 months ago by jchanut

Hi Andrea,

The "weird" salinity values you see under the overlap come from the parent/child volume mismatch (at rest). When less than 50% of a surface parent grid cell is not covered by child grid cells, a specific procedure is used, and volume matching is lost (this prevent from having tiny depths on parent grid). This typically occurs near the coastline. Everything's happen in the Nesting tool here so that's not related to what is actually done in NEMO. This said, it's probably worth checking that the domain file shipped with AGRIF_DEMO for zoom 2 has been updated by the zoom 3, because normally, in that case, a parent grid cell should be masked.

In the feedback stage done by agrif on the parent grid cell, the update is a volume weighted average of tracers in the vvl case. This is done to conserve tracer content. This explain why you see the problem only with ln_linssh=.false.

However, tracer values under the overlap should not have big consequences on your solution, because only the last level of zoom dynamically matters. That's rather a cosmetic issue to me.

How weird are the salinity values ?
Do you use the updated parent grid created by the tools ?

Jérôme

comment:2 in reply to: ↑ 1 Changed 3 months ago by andrea.gierisch

Hi Jérôme,

Thanks for your explanations!

The "weird" salinity values you see under the overlap come from the parent/child volume mismatch (at rest). When less than 50% of a surface parent grid cell is not covered by child grid cells, a specific procedure is used, and volume matching is lost (this prevent from having tiny depths on parent grid). This typically occurs near the coastline. Everything's happen in the Nesting tool here so that's not related to what is actually done in NEMO.

Do I understand it correctly that you say these "weird" salinity values are kind of expected, because they arise from the mismatch of bathymetry/volume in child and parent? I fully understand that it is a tricky situation if a parent cell overlaps with land in the nest. But I don't yet see why I would expect a salinity change in this case. Or is it all about salt conservation, so that the salinity in a parent cell that is covered by 25% of child-land should for example be 24 psu if the child has 32 psu?

—-

This said, it's probably worth checking that the domain file shipped with AGRIF_DEMO for zoom 2 has been updated by the zoom 3, because normally, in that case, a parent grid cell should be masked.

Aha, so the rule is that if a parent cell is covered by more than 50% of child-land, the NESTING-tool should mask it as land?
I don't think this is currently true for 2_Nordic and 3_Nordic. Look e.g. at Kvitøya ((North-)East of Svalbard).

—-

However, tracer values under the overlap should not have big consequences on your solution, because only the last level of zoom dynamically matters. That's rather a cosmetic issue to me.

Yes, it might usually not matter too much. Especially not in the AGRIF_DEMO case where there is no land at the nest-boundaries. In my own domain, however, I have a lot of land at the boundaries, so couldn't it become a problem there if the "weird" salinity values are fed back from the parent to the child at the boundaries?

—-

How weird are the salinity values ?

In AGRIF-DEMO not too much, something like 0.5 psu. But in my domain I reach differences of up to 6 psu.

—-

Do you use the updated parent grid created by the tools ?

Yes.

—-

In the feedback stage done by agrif on the parent grid cell, the update is a volume weighted average of tracers in the vvl case. This is done to conserve tracer content. This explain why you see the problem only with ln_linssh=.false.

I guess you talk about the subroutine updateTS defined in line 397 of NST/agrif_oce_update.F90 ?
https://forge.ipsl.jussieu.fr/nemo/browser/NEMO/releases/r4.0/r4.0.2/src/NST/agrif_oce_update.F90#L397

tsn gets scaled by e3t before/after exchanging it. It is indeed these multiplications/divisions with e3t, which cause the "weird" salinities. In a test, I removed all calculations involving e3t and that made the results look much better/correct. Here the code changes:

  • agrif_oce_update.F90

     
    412412               DO jj=j1,j2 
    413413                  DO ji=i1,i2 
    414414!> jc tmp 
    415                      tabres(ji,jj,jk,jn) = tsn(ji,jj,jk,jn)  * e3t_n(ji,jj,jk) / e3t_0(ji,jj,jk) 
     415                     tabres(ji,jj,jk,jn) = tsn(ji,jj,jk,jn) 
     416                     !tabres(ji,jj,jk,jn) = tsn(ji,jj,jk,jn)  * e3t_n(ji,jj,jk) / e3t_0(ji,jj,jk) 
    416417!                     tabres(ji,jj,jk,jn) = tsn(ji,jj,jk,jn)  * e3t_n(ji,jj,jk) 
    417418!< jc tmp 
    418419                  END DO 
     
    422423      ELSE 
    423424!> jc tmp 
    424425         DO jn = 1,jpts 
    425             tabres(i1:i2,j1:j2,k1:k2,jn) =  tabres(i1:i2,j1:j2,k1:k2,jn) * e3t_0(i1:i2,j1:j2,k1:k2) & 
     426            tabres(i1:i2,j1:j2,k1:k2,jn) =  tabres(i1:i2,j1:j2,k1:k2,jn) & 
    426427                                         & * tmask(i1:i2,j1:j2,k1:k2) 
    427428         ENDDO 
    428429!< jc tmp 
     
    433434                  DO jj = j1, j2 
    434435                     DO ji = i1, i2 
    435436                        IF( tabres(ji,jj,jk,jn) /= 0._wp ) THEN 
    436                            ztb  = tsb(ji,jj,jk,jn) * e3t_b(ji,jj,jk) ! fse3t_b prior update should be used 
     437                           ztb  = tsb(ji,jj,jk,jn) ! fse3t_b prior update should be used 
    437438                           ztnu = tabres(ji,jj,jk,jn) 
    438                            ztno = tsn(ji,jj,jk,jn) * e3t_a(ji,jj,jk) 
     439                           ztno = tsn(ji,jj,jk,jn)  
    439440                           tsb(ji,jj,jk,jn) = ( ztb + atfp * ( ztnu - ztno) )  &  
    440                                      &        * tmask(ji,jj,jk) / e3t_b(ji,jj,jk) 
     441                                     &        * tmask(ji,jj,jk)  
    441442                        ENDIF 
    442443                     END DO 
    443444                  END DO 
     
    449450               DO jj=j1,j2 
    450451                  DO ji=i1,i2 
    451452                     IF( tabres(ji,jj,jk,jn) /= 0._wp ) THEN  
    452                         tsn(ji,jj,jk,jn) = tabres(ji,jj,jk,jn) / e3t_n(ji,jj,jk) 
     453                        tsn(ji,jj,jk,jn) = tabres(ji,jj,jk,jn)  
    453454                     END IF 
    454455                  END DO 
    455456               END DO 

My hypothesis why this change could lead to more correct results is the following:
Let's assume a case where e3t0 is the same for parent and child (like it is true for the AGRIF_DEMO case). Let's look at a parent cell which maybe has a depth of 3 levels and is covered in the nest by one land-child-cell and one child cell with a depth of 6 levels. If the sea level rises by dH, e3t in the parent increases by 1/3*dH and in the child by 1/6*dH (I'm not certain that it's exacly like this, but at least e3t would change more for the parent than for the child, because it has less cells. Right?) Now, in the case of updateTS, the parent-salinity S_0 is basically calculated from the child-salinity S_1 as:

$ S_0 = S_1 \cdot \frac{e3t_1}{e3t0_1}  / \frac{e3t_0}{e3t0_0} = S_1 \cdot \frac{e3t_1}{e3t_0} $

The e3t0 cancel because they are the same for parent and child. And as e3t_1 (of the child) is less than e3t_0 (of the parent), because the sea level rise is spread over more vertical cells, the salinity is reduced (or increased, if the sea level drops).

This would be my explanation, but please correct me if my understanding is wrong or I use wrong assumptions. Especially I'm not 100% sure how e3t is exactly treated in the vvl-case. Also, I don't have an overview of what other implications my code change would have on the rest of the code. For now I can just say that salinity in the parent (2_Nordic) "looks" better now. I'll attach a plot.

Best regards,
Andrea

Changed 3 months ago by andrea.gierisch

AGRIF_DEMO: Salinity in parent after removing e3t in the code

Note: See TracTickets for help on using tickets.