Skip to content
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

Bug fixes in Redi and new tapering options #445

Merged

Conversation

vanroekel
Copy link
Contributor

This PR fixes a few issues with the Redi mixing implementation and also adds tapering based on Danabasoglu and McWilliams 95 and Large et al 1997.

@vanroekel
Copy link
Contributor Author

Here is a plot of minimum temperature from the tests (black is the latest from this PR). This is an E3SM G-case. We are evaluating after 30 years of simulation.

Screen Shot 2020-02-04 at 10 00 35 PM

dzTop(maxLevelCell(sVal)+1) = -1e-15_RKIND
dTdzTop(maxLevelCell(sVal)+1) = -1e-15_RKIND
dSdzTop(maxLevelCell(sVal)+1) = -1e-15_RKIND

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to compute dtdz and dsdz each time. There are times when the stratification is computed for iCell but this is not consistent with iCellSelf. This makes most sense to me comparing to the picture in Griffies et al 1998


modifiedGroupName = trim(groupItr % memberName) // "_redi_term3"
call mpas_pool_get_array(redi3Pool, trim(modifiedGroupName), redi_term3)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these output the individual redi terms (except vertical mixing). we can revert these when we want to merge.

@@ -216,12 +218,13 @@ subroutine ocn_tracer_hmix_Redi_tend(meshPool, scratchPool, layerThicknessEdge,

! For top layer, only use triads pointing down:
flux_term2 = coef * RediKappa(iCell) * layerThicknessEdge(k, iEdge) * &
0.5_RKIND * &
0.25_RKIND * &
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to treat the top and bottom as an average of 4 things even though there are just two. I think of it as an average of 4 triads still but 2 are zero.

@@ -317,7 +323,8 @@ subroutine ocn_tracer_hmix_Redi_tend(meshPool, scratchPool, layerThicknessEdge,
flux_term3 = RediKappa(iCell) * 2.0_RKIND * &
(fluxRediZTop(iTr,k)/areaSum(k) - fluxRediZTop(iTr,k+1)/areaSum(k+1))

tend(iTr,k,iCell) = tend(iTr,k,iCell) + flux_term3
redi_term3(iTr,k,iCell) = redi_term3(iTr,k,iCell) - flux_term3
tend(iTr,k,iCell) = tend(iTr,k,iCell) - flux_term3
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the most critical change. It was not clear to me why flux_term3 had a positive on it and was the dominant term of 1-3 in my testing that seemed to cause the large negative temperatures. This seems to fit best with the equation for the Redi term you had on confluence.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Term 3 is d/dz ( h S dot grad phi) = ( S dot grad phi) where grad phi is computed on the edge and middle vertically, and then multiplied by the slope triad that goes through that edge. I don't expect a negative sign here. But just in case, I made this change in the current head of ocean/develop and reran this idealized SO test case.
output
Compare to identical repo with positive sign on term 3:
#280 (comment)
image
Also, the analytic polynomial test cases match with a positive sign but not a negative sign.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mark-petersen, I agree the sign is correct as positive, I still don't fully understand why though.

@vanroekel
Copy link
Contributor Author

vanroekel commented Feb 12, 2020

@mark-petersen I've been thinking more about redi term3 and had a question about the fluxRediZtop code (here

do iTr = 1, nTracers
! Gradient of tracer at edge.
! dvEdge on following line is equal to areaEdge/dcEdge
dTracerDx = (tracers(iTr,k,cell2) - tracers(iTr,k,cell1)) * dvEdge(iEdge)
fluxRediZTop(iTr,k) = fluxRediZTop(iTr,k) + &
slopeTriadUp(k,iCellSelf,iEdge) * dTracerDx
fluxRediZTop(iTr,k+1) = fluxRediZTop(iTr,k+1) + &
slopeTriadDown(k,iCellSelf,iEdge) * dTracerDx
end do
end do
end do
). When I look at this it seems there are only two triads being considered for each edge. The previous code (redi term2) has an explicit loop over iCellSelf (including 1 and 2) but here only seems to have one value per edge. Shouldn't this be an average of the 4? I'm sure I'm not understanding something in the implementation.

@vanroekel
Copy link
Contributor Author

@mark-petersen I think this PR is ready now. Here is the latest plot of temperature min from @jonbob's E3SM run. There is something weird at year 20, but overall this looks good.
Screen Shot 2020-02-18 at 10 11 23 PM

@mark-petersen
Copy link
Contributor

That plot is with the single-cell pits, right? When the single-cell pits were removed, did the min remain at -1.8, even if it was just MPAS-Ocean stand alone?

@milenaveneziani
Copy link
Contributor

Aren't you concerned about all the values with T<-2?

@vanroekel
Copy link
Contributor Author

The min temperature remained above -2 for most of the run. Something weird is indeed happening at year 20. It does recover to be above -2 again quickly. I will take a look at that time period. Other than those few years things look good.

This is the case with no single cell pits. So I'm not sure why we are getting that period. Jon saved extra output so I should be able to see what is happening.

@jonbob
Copy link
Contributor

jonbob commented Feb 19, 2020

@vanroekel - let me know if I should rerun that time. And I'll check the output to make sure nothing suspicious has happened....

@jonbob
Copy link
Contributor

jonbob commented Feb 19, 2020

I looked more closely at the output and the log files -- there's an almost linear decrease in the minimum temperature starting very close to the beginning of year 20. Nothing in the logs jumps out to indicate something going off the rails

@vanroekel
Copy link
Contributor Author

@mark-petersen I've looked through the 30 years of simulation from @jonbob. The negatives are most often right near the bottom, but there are a few further up in the column (layer 14 when max level cell = 21). So it looks like bottom tapering could help, but may not completely fix the problem.

@mark-petersen
Copy link
Contributor

OK. It sounds like bottom tapering is still worth trying.

! Griffies 1998 eqn 34
k33(k ,iCell) = k33(k ,iCell) + slopeTaperUp * sfcTaperUp * &
areaEdge*dzTop(k)*slopeTriadUp(k,iCellSelf,iEdge)**2
k33(k+1,iCell) = k33(k+1,iCell) + slopeTaperDown * sfcTaperDown * &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vanroekel, these k33 lines were moved up in the last commit, but they still have the taper coefficients, same as slopeTriadUp and slopeTraidDown. The plan was to not taper k33, right? So shouldn't the slope taper variables not appear in the above lines?

@vanroekel
Copy link
Contributor Author

update, after the new commit, here are the results of min temperature after 1 year. Blue is before the latest commit and orange is the latest
Screen Shot 2020-02-25 at 1 57 49 PM

@milenaveneziani
Copy link
Contributor

Looks great!

@vanroekel
Copy link
Contributor Author

Okay, I've gone through and made a number of new changes, including tapering based on N2 (like Danabasoglu and Marshall 1997), I've also added a convective trigger. I've tested briefly in stand alone, things are looking good so far!

Screen Shot 2020-02-28 at 11 52 44 AM

@vanroekel
Copy link
Contributor Author

I should mention the orange line is the commit with the r value fix, and blue is the latest commit.

@milenaveneziani
Copy link
Contributor

Great. I can run a G-case whit E3SM when we are ready.

@vanroekel
Copy link
Contributor Author

Thanks @milenaveneziani for offering to do the run. I had asked @jonbob to pull the code together for the E3SM run and he already submitted the test. 4 months in, things look good!

Also, through 6 months of stand alone results look good as well.

@vanroekel
Copy link
Contributor Author

@mark-petersen this branch now has options to disable all tapering. To remove tapering on everything do

config_Redi_diabatic_limit = 1e6
config_Redi_use_slope_taper = .false.
config_Redi_use_surface_taper = .false.
config_Redi_N2_limit_term1 = .false.
config_GM_closure = 'constant'

Jon is testing the new limiting of term1 in a g-case now.

@vanroekel
Copy link
Contributor Author

@mark-petersen I just pushed my latest code with some changes to tapering and disabling terms 2 and 3 in the bottom cell. Could you test your convergence on this commit and let me know how it goes.

@mark-petersen
Copy link
Contributor

@vanroekel I find these descriptions confusing:

 398     <nml_option name="config_Redi_half_slope" type="real" default_value="0.004" units="non-dimensional"
 399         description="value of slope where set to half max"
...
 402     <nml_option name="config_Redi_half_width" type="real" default_value="0.001" units="non-dimensional"
 403         description="value of half width of tanh function limiter"

Could you replace the description with something like

nml_option name="config_Redi_half_slope"
"The isopycnal slope used in the Redi calculation is limited by the 
function $equation here$ (see Authors et al eqn. XX). 
config_Redi_half_slope is $\variable$ and is the slope value where the limiting is 1/2 
(i.e. the center of the tanh function)"

and similar for config_Redi_half_width. Thanks!

@mark-petersen
Copy link
Contributor

@vanroekel The head is still bfb with your last commit 2f74e37 on the MPAS-Ocean nightly regression suite. Please check in your standard E3SM set-up. Should be bfb there as well, as changes were all omp and formatting, and removing unused variables.

This is almost ready to merge. I'm rechecking convergence and idealized Redi test now.

@vanroekel
Copy link
Contributor Author

@mark-petersen I'm building a case with your latest changes now. I should have something for you by tomorrow morning at the latest.

@vanroekel
Copy link
Contributor Author

@mark-petersen I can confirm that the latest commit is BFB with my previous e3sm tests.

@mark-petersen
Copy link
Contributor

Automated tests all look good.
convergence
output

@mark-petersen mark-petersen self-requested a review April 16, 2020 03:46
Copy link
Contributor

@mark-petersen mark-petersen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now passes all the tests and is read to merge.

@vanroekel
Copy link
Contributor Author

Great! Thanks for all the help getting this across the finish line. I agree this is ready to merge.

Matches bfb with previous
@@ -1647,7 +1626,8 @@
mode="forward;analysis">

<stream name="mesh"/>
<var_struct name="tracers"/>
<var_struct name="tracers"/>
<var name="indMLD"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vanroekel I'm taking a last careful look through. We added indMLD to the restart file here when we were struggling with the restart bug, but I don't think it is needed. The restart test passes without it, with Redi and GM on. Do you agree it can be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. I believe rediGM is now called before the timestep but after the analysis compute, but this might require that MLD be computed on start up. Is that flag set in your testing? If we don't compute on start up we may want to keep indMLD in the restart file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it depends on the timing of the mixedLayerDepths AM. We can only safely remove the variable if the AM is computed just before the restart is written, to get exact restarts. For example, if we use either of these settings:

config_AM_mixedLayerDepths_compute_interval = 'dt'
config_AM_mixedLayerDepths_compute_interval = '01_00:00:00'

for a global run, we can remove indMLD from the restart file. The safest option is to leave it in, at the cost of a slightly larger restart file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree for nearly all E3SM cases this won't be an issue, but it might be safest to just leave it in.

@@ -1657,6 +1637,7 @@
<var name="xtime"/>
<var name="simulationStartTime"/>
<var name="boundaryLayerDepth"/>
<var name="indexBoundaryLayerDepth"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here. My restart test passes using QU240 and cvmix on, using kpp, with both boundaryLayerDepth and indexBoundaryLayerDepth removed. Are there conditions where those variables are used from the previous timestep, rather than recomputed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed. I think this was from your first tapering implementation when it was based on BLD. I'm sure it can be removed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about boundaryLayerDepth in the restart file? That was added a long time ago. Probably before the cvmix:

cb8195861b (Douglas Jacobsen   2015-02-02 13:45:52 -0700 1659)          <var name="boundaryLayerDepth"/>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of any reason to include boundaryLayerDepth in the restart file. It is always computed before mixing and is only used within the mixing routine. So I don't think that should affect restarts.

removed:
boundaryLayerDepth
indexBoundaryLayerDepth
@mark-petersen mark-petersen merged commit 8326fbb into MPAS-Dev:ocean/develop Apr 16, 2020
@xylar
Copy link
Collaborator

xylar commented Apr 16, 2020

Congratulations! This was clearly a lot of work!

call ocn_gm_compute_Bolus_velocity(diagnosticsPool, meshPool, scratchPool)
end if
! if (config_use_GM.or.config_use_Redi) then
! call ocn_gm_compute_Bolus_velocity(statePool, diagnosticsPool, &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vanroekel I saw that this line is commented out in ocean/develop, and looks like we were in a rush and left some confusing code. This was commented out in this PR in:
66a13d9 fixes for restart test
We changed E3SM to call this routine from the driver:

components/mpas-ocean/driver/ocn_comp_mct.F:968:
             call ocn_gm_compute_Bolus_velocity(statePool, diagnosticsPool, meshPool, scratchPool, timeLevelIn=1)

in E3SM-Project/E3SM@b29cfe5b370 (Luke Van Roekel 2020-05-05 16:01:43 -0500 968)
but it appears that it is not called from the driver in stand-alone. I can make an issue to clean this up, but wanted to ping you on these lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes @mark-petersen I removed those calls and moved them to the driver, I just never removed them. I can clean this up if you want. It should be in stand alone as you note below

end if
! ! Compute normalGMBolusVelocity; it will be added to normalVelocity in Stage 2 of the next cycle.
! if (config_use_GM.or.config_use_Redi) then
! call ocn_gm_compute_Bolus_velocity(statePool, diagnosticsPool, &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line was also commented out, and needs to be removed or cleaned up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes those can be removed

call ocn_tidal_forcing_build_array(domain, meshPool, forcingPool, diagnosticsPool, statePool, err)

! Compute normalGMBolusVelocity, relativeSlope and RediDiffVertCoef if respective flags are turned on
if (config_use_Redi.or.config_use_GM) then
call ocn_gm_compute_Bolus_velocity(statePool, diagnosticsPool, meshPool, scratchPool, timeLevelIn=1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the stand-alone call is here, so maybe this is just a matter of removing the commented out lines for clarity.

if (config_use_standardGM) then
call ocn_gm_compute_Bolus_velocity(diagnosticsPool, meshPool, scratchPool)
if (config_use_GM) then
call ocn_gm_compute_Bolus_velocity(statePool, diagnosticsPool, &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In rk4, the corresponding lines here should also be removed, since it is called from the driver.

caozd999 pushed a commit to caozd999/MPAS-Model that referenced this pull request Jan 14, 2021
…/develop

Bug fixes in Redi and new tapering options MPAS-Dev#445

This PR fixes a few issues with the Redi mixing implementation and also
adds tapering based on Danabasoglu and McWilliams 95 and Large et al
1997.
xylar added a commit to xylar/compass that referenced this pull request Aug 13, 2021
The mixed layer depth analysis member was enabled and writing out
analysis at every time step for all global ocean forward model
runs.  This appears to have been turned on for debugging in a
pull request from more than a year ago
(MPAS-Dev/MPAS-Model#445).  During
dynamic adjustment, this can lead to files that are many GB in size
and presumably slows down all model runs significantly.
xylar added a commit to xylar/compass that referenced this pull request Aug 13, 2021
The mixed layer depth analysis member was enabled and writing out
analysis at every time step for all global ocean forward model
runs.  This appears to have been turned on for debugging in a
pull request from more than a year ago
(MPAS-Dev/MPAS-Model#445).  During
dynamic adjustment, this can lead to files that are many GB in size
and presumably slows down all model runs significantly.
xylar added a commit to xylar/compass that referenced this pull request Aug 13, 2021
The mixed layer depth analysis member was writing out analysis from
every time step for all global ocean forward model runs.  The MLD
AM was turned on for every time step in
MPAS-Dev/MPAS-Model#445 and output in
legacy compass was set to every day.  But in the compass package,
output is every time step.  During dynamic adjustment, this can
lead to files that are many GB in size and presumably slows down
all model runs significantly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants