-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updates to Redi scheme #117
base: master
Are you sure you want to change the base?
Updates to Redi scheme #117
Conversation
Redi is set to GM and the taper is fixed to be consistent with Danabasoglu and Marshall 2007
There are cases where the density threshold MLD < BLD. In these cases, the MLD for the transition layer in the Redi scheme is set to BLD + the config flag value
Initial results from a G-case This PR - https://web2.lcrc.anl.gov/public/e3sm/diagnostic_output/ac.vanroekel/icos_rediks_yr_11_20/ |
@jonbob - could you please run the namelist scripts for the new config option on this branch when you have a minute? |
also pinging @maltrud, @irenavankova, and @proteanplanet as an FYI. |
OK, I had to fix some text in Registry that caused the xml parser to fail -- so please make sure you're OK with it. Otherwise I ran the scripts to make the bld files consistent and pushed the updates to your branch |
Thanks @jonbob - I think the changes are okay, but may change |
Thanks @vanroekel -- that makes sense. We'll have to change it to match in the namelist definitions file |
I did some tests with Luke's changes when I was looking into GM tuning for polar SORRM configuration, focusing on Amundsen and Amery regions. Because the changes are quite impactful I want to bring them up here. What I found is that there are some quite significant changes in ice-shelf cavities and around the continental shelves of Antarctica. Specifically mixed layer deepens a lot in the cavities and also around the coast. With the N2_dependent option there is a very high increase in melt rates, especially at the large cold cavities. I think these high melt rates are not driven by intrusions at depth (if anything sea-floor continental shelf temperatures cool slightly), but by a decrease in locally formed cold dense water. As a result we essentially stop producing Ice Shelf Water as indicated by the absence of basal freezing. I can recover the lower ice shelf melt rates, but for that need very low GM/Redi kappas and then the Antarctic slope front looks unrealistic compared to observations. I just made a confluence page on those simulations here, and posted links to analysis etc there: I wanted to point out that this is with a V2 mesh, and a bit older code base - I was using a reference case from August for comparisons that I had sufficiently spun up. I merged Luke's changes with the old branch and there were no conflicts. |
I suggested to @irenavankova that she confirm this problem in the SORRM V3 alfred1 B-case configuration. Tagging @darincomeau and @cbegeman |
@irenavankova thanks for the analysis, could I ask a few questions?
Thinking about it there may need to be a different rotation of the flux to dampen the cross mixed layer transport. I'd be happy to talk about this further with you or any others on the polar team |
I will discuss with Luke tomorrow and coordinate more tests afterwards. |
In pondering this further, I want to make some changes to this branch before more testing commences. I'll try do that today. @irenavankova I'll show you the changes tomorrow. |
1. allows redi to be constant when gm=N2_dependent 2. improves the new boundary layer taper for less entrainment 3. reinstates original N2_dependent as a new option 'N2_dependent_orig'
!$omp do schedule(runtime) private(k) | ||
do iEdge = 1,nEdges | ||
do k = minLevelEdgeBot(iEdge),maxLevelEdgeTop(iEdge) | ||
RediKappa(k,iEdge) = gmKappaScaling(k,iEdge)*RediKappa(k,iEdge) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am probably missing something here, but wanted to clarify anyway. As of now it seems that RediKappa is not getting multiplied by RediHorizontalTaper when config_Redi_closure == 'N2_dependent'. Also, it is not clear to me why RediKappa needs to be multiplied by gmKappaScaling in the config_Redi_closure == 'N2_dependent' case - they were both calculated above and are very similar, I thought that calculation (when local_config_GM_kappa_lat_depth_variable) already introduced the N2 dependency into RediKappa.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Thanks. The lines above where it is calculated need to be removed. With two versions of N2_dependent I didn't want to calculate the Redi twice, so in this way, RediKappa gets the original N2_dependent scaling or the new one depending on the choices, but I forgot to delete the one above
RediKappa(iEdge) = gmHorizontalTaper(iEdge) * gmBolusKappa(iEdge) | ||
do k = minLevelEdgeBot(iEdge),maxLevelEdgeTop(iEdge) | ||
RediKappa(k,iEdge) = gmHorizontalTaper(iEdge) * gmBolusKappa(iEdge) | ||
end do | ||
end do | ||
!$omp end do | ||
!$omp end parallel | ||
else if (config_Redi_closure == 'constant'.and. & | ||
config_Redi_horizontal_taper == 'RossbyRadius') then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this done only for RossbyRadius and not for any RediHorizontalTaper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I'm not sure what you are pointing at here. Can you explain what you mean by 'this'? Maybe you mean why there is no 'ramp' here? If so, that's applied in mpas_ocn_tracer_hmix_redi.F toward the bottom (in the init routine). The ramp taper is constant so it's applied once. However, if we move to a separate N2 dependent that varies in time we do need to apply the taper every time and can't assume it's already in RediKappa. I'll fix that. If that's not what you mean here, let me know
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know what you think of the fix I've proposed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is what I was refering to, I am not seeing where RediKappa is multiplied by RediHorizontalTaper in a situation where RediHorizontalTaper = 'ramp'. But yes, I see that in the constant case neither field is evolving so that case can be only done in init. I was also thinking more generally though, when we introduce another taper - like the one from the Dettling paper (slope dependent) that this could be handled in the same place for all tapers, but maybe that is not the most efficient way computationally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the clarification. I think what I changed will do what you need. See line 765. But it is just if N2_dependent is chosen, maybe better is
config_Redi_closure .ne. 'constant' .or. config_Redi_closure .ne. 'equalGM'
what do you think?
limiterUp(k,iCellSelf,iEdge) = slopeTaperUp !1.0_RKIND !(1.0_RKIND - RediKappaSfcTaper(k,iEdge)* & | ||
! (1.0_RKIND - slopeTaperUp)) | ||
limiterDown(k,iCellSelf,iEdge) = slopeTaperDown! 1.0_RKIND !(1.0_RKIND - RediKappaSfcTaper(k,iEdge))!* & | ||
! (1.0_RKIND - slopeTaperDown)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@irenavankova these lines are important to pick up in your runs.
!$omp do schedule(runtime) private(k) | ||
do iEdge = 1,nEdges | ||
do k = minLevelEdgeBot(iEdge),maxLevelEdgeTop(iEdge) | ||
RediKappa(k,iEdge) = RediHorizontalTaper(iEdge)*gmKappaScaling(k,iEdge)*RediKappa(k,iEdge) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the horizontal taper here as it will be the ramp, one, or rossby radius depending on parameters
cell2 = cellsOnEdge(2, iEdge) | ||
|
||
bldEdge = 0.5_RKIND*(boundaryLayerDepth(cell1) + boundaryLayerDepth(cell2)) | ||
mldEdge = config_redi_transition_layer_mld_offset*bldEdge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think mldEdge is used in the code anymore, so can be deleted?
But if it were - then with the default value of 100 m it would be very large - is that intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you are right, I rewrote to not use it, but I think we should keep it for now. We may want to consider having this approach in cavities and a different one globally. And yes 100m is very large that was the default I tried, but we'd probably want something closer to a couple of grid cells (20-50m)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so can we rename config_redi_transition_layer_mld_offset in Registry to something like: The fraction of boundary layer depth where RediKappaSfcTaper begins to transition linearly from 0 to 1, where 1 is reached at boundary layer depth.
And also change units to unitless and default to something between 0 and 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's right, I'll do that when we settle on the final form
@vanroekel I wanted to double check with you about where in vertical space you evaluate My reading of the code is that you are doing:
And I'm wondering if it should be:
In other words, This comment perhaps belong here #113. |
Good question @cbegeman. I think what I have isn't quite right, but I think it also needs to be different from what you have as well. the dTdx lives on the edge in the middle of the cell (as defined by Griffies 1998 - https://journals.ametsoc.org/view/journals/phoc/28/5/1520-0485_1998_028_0805_idiazc_2.0.co_2.xml). I would cast this as
This is a correction from index space to physical depth space, so not a movement to the top. Diffusivity is at the top, but it's a combination of the slope which is formed by dTdx_z_center and dTdz_top (equation 34 of griffies 1998) But right now, I have dTdz_top and dzdx_top (zmid(k) - zmid(k+1)) I think would live at the cell top, but those should be in the centers. Does that make sense? |
@vanroekel Yes, what you proposed looks consistent with evaluating dTdz at the centers. Thanks! |
This addresses the need to transition the Redi isopycnal mixing scheme from isopycnal at depth to pure horizontal mixing in the surface boundary layer (see, e.g. - https://journals.ametsoc.org/view/journals/clim/21/6/2007jcli1508.1.xml). Currently the default behavior of master is to taper redi to zero in the BLD. To accomplish this, the
RediKappa
array is now 3d to allow for horizontal variability of the boundary layer and mixed layer depths. The transition is linear between the density threshold mixed layer depth and the boundary layer depth. There are places when the MLD is shallower than the BLD. In these cases, the MLD is set to BLD + a config flag option (config_redi_transition_layer_mld_offset
).The temperature and salinity gradients are also converted from model index space to z-coordinates. This addresses #113 - this part can easily be separated out in a final E3SM pull request.