Add SAL updates and topographic wave drag schemes for barotropic tides#6310
Conversation
- Include pressure forcing term in SAL computation to account for under isc and atm pressure cases. - Update SAL coastal smoothing factor to mask shallow cells where wet-dry effects may occur out of SAL computation. - Compute harmonic analysis AM wrt. SSH-SSH_init to account for initially non-zero SSH distributions.
- Add missing rho0gInv definition.
- Clean up descriptions, comments and use real-valued switches.
- Change sshSmoothed to btrPressure in SAL routines, since we're now working with surface pressures too.
…y instead of subtracted.
| ! Set up coastal ssh smoothing | ||
| allocate(sshSmoothed(nCellsAll)) | ||
|
|
||
| if (config_self_attraction_loading_smoothing_width > 2.0_RKIND) then | ||
| trans_width = config_self_attraction_loading_smoothing_width*1000.0_RKIND | ||
| trans_start = 0.0_RKIND | ||
| do iCell = 1,nCellsAll | ||
| d = distanceToCoast(iCell) | ||
| coastalSmoothingFactor(iCell) = 0.5_RKIND*(tanh((d - trans_start - 0.5_RKIND * trans_width) / (0.2_RKIND *trans_width)) + 1.0_RKIND) | ||
| enddo | ||
| else | ||
| coastalSmoothingFactor(:) = 1.0_RKIND | ||
| endif | ||
| ! Set up coastal smoothing | ||
| allocate(btrPressure(nCellsAll)) | ||
|
|
||
| ! Set-up smoothing mask for shallow regions where SAL should not | ||
| ! be computed across e.g. wet-dry cells | ||
| depth_tol = config_self_attraction_loading_depth_cutoff | ||
| do iCell = 1,nCellsAll | ||
| depth = ssh(iCell) + bottomDepth(iCell) | ||
| coastalSmoothingFactor(iCell) = 0.5_RKIND*(tanh( & | ||
| (depth - 0.5_RKIND*depth_tol) / (0.2_RKIND*depth_tol)) + 1.0_RKIND) | ||
| enddo | ||
|
|
There was a problem hiding this comment.
This is the switch from distance-based to depth-based SAL smoothing
| sshSmoothed(iCell) = coastalSmoothingFactor(iCell)*ssh(iCell) | ||
| ! compute SAL wrt. the full barotropic bottom pressure | ||
| btrPressure(iCell) = coastalSmoothingFactor(iCell) * ( & | ||
| ssh(iCell) + rho0gInv * surfacePressure(iCell) ) |
There was a problem hiding this comment.
This is where the surface pressure is added to the SAL calculation
| allocate(sshDiff(nCellsSolve)) | ||
|
|
||
| do iCell = 1,nCellsSolve | ||
| sshDiff(iCell) = ssh(iCell) - sshInit(iCell) | ||
| end do | ||
|
|
There was a problem hiding this comment.
This is the change that makes the harmonic analysis work on the ssh anomaly.
| <var name="temp_twd"/> | ||
| <var name="normalCoeff"/> | ||
| <var name="tangentialCoeff"/> | ||
| <var name="topographicWaveDrag"/> |
There was a problem hiding this comment.
I don't believe these need to be in the restart stream, since they are calculated in an init routine
| topographicWaveDrag = topographicWaveDragCoeff & | ||
| * topoDragTurnOff & | ||
| * (sqrt((topo_buoyancy_N1B(iEdge)**2 - omegaM2**2) * & | ||
| (topo_buoyancy_N1V(iEdge)**2 - omegaM2**2))) & | ||
| / (4*pii*omegaM2) | ||
| normalCoeff = (lonGradEdge(iEdge)**2) * & | ||
| (cos(angleEdge(iEdge))**2) + (latGradEdge(iEdge)**2)*(sin(angleEdge(iEdge))**2) - & | ||
| 2*latGradEdge(iEdge)*lonGradEdge(iEdge)*sin(angleEdge(iEdge))*(cos(angleEdge(iEdge))) | ||
| tangentialCoeff = sin(angleEdge(iEdge)) * & | ||
| cos(angleEdge(iEdge)) * & | ||
| (lonGradEdge(iEdge)**2 - latGradEdge(iEdge)**2) + & | ||
| latGradEdge(iEdge)*lonGradEdge(iEdge)*(cos(angleEdge(iEdge))**2 - sin(angleEdge(iEdge))**2) |
There was a problem hiding this comment.
These variables should be indexed, i.e., topographicWaveDrag(iEdge) = , normalCoeff(iEdge) =, tangentialCoeff(iEdge) =
There was a problem hiding this comment.
I'm not sure what fortran will do in this case, but I feel like testing for LGF should be revisited...
There was a problem hiding this comment.
I'm pretty sure it'll set the entire array to a single value, so this definitely needs to be retested.
| topographicWaveDrag(iEdge) = 0.0_RKIND | ||
| if (kmax > 0) then | ||
| k = maxLevelEdgeTop(iEdge) | ||
| topoDragTurnOff = (TANH((layerThickEdgeMean(k,iEdge)-topoDragCutoffDepth)/topoDragCutoffWidth)+1)/2 |
There was a problem hiding this comment.
I think I'm going to pull out the application of the topoDragTurnOff factor since it's common to all three drag schemes
| ! topographic_wave_drag = 1/rinv | ||
| if (k>0) then | ||
| temp_twd(iEdge) = topographicWaveDrag(iEdge) * normalVelocity(k,iEdge) | ||
| tend(k,iEdge) = tend(k,iEdge) - topographicWaveDrag(iEdge) * normalVelocity(k,iEdge) |
There was a problem hiding this comment.
We should just set tend(k,iEdge) = tend(k,iEdge) - temp_twd(iEdge)
| topoDragTurnOff = (TANH((layerThickEdgeMean(k,iEdge)-topoDragCutoffDepth)/topoDragCutoffWidth)+1)/2 | ||
| topographicWaveDrag(iEdge) = topographicWaveDragCoeff*topoDragTurnOff*50.0_RKIND * & | ||
| (bed_slope_edges(iEdge)**2) * & | ||
| (5.24e-3_RKIND*1300.0_RKIND * & |
There was a problem hiding this comment.
These should be defined as constant variables
| <nml_option name="config_topographic_wave_drag_coeff" type="real" default_value="5.0e-4" | ||
| <nml_option name="config_topographic_wave_drag_scheme" type="character" default_value="JSL" units="unitless" | ||
| description="hich of the following three wave drag schemes to use: JSL: Jayne and St. Laurent; ZAE: Zaron and Egbert; or LGF: Local generation formula" | ||
| possible_values="JSL or ZAE or LGF" |
There was a problem hiding this comment.
Is the implementation/tuning for LGF well established? I know that JSL and especially ZAE are working well, but am less confident re: LGF.
Should ZAE be the default if it's typically the best performing?
There was a problem hiding this comment.
Having ZAE as the default sounds good to me. I'm going to do a full tidal run with all three and I'll report back on the errors. I believe that LGF needs to be re-evaluated given the indexing issue I found above.
|
@dengwirda, I confirmed that with the LGF changes described above (e.g. MPAS-Dev/compass@ab0da31), the model achieves a 3.36 cm deep M2 RMSE with a wave drag coefficient of 2.5. That wave drag value is much more reasonable and is solidly in the rage used by ADCRIC (See figure 6 here). While I haven't done a full set of tuning runs to find an optimal value, this result gives me a lot more confidence that LGF is working correctly. |
|
Looks good @sbrus89! Those array indexing issues must have been where the issues with LGF had been lurking in the past. |
|
@jonbob, this one is ready now when convenient. |
|
@dengwirda - no problem, I'm glad we got it sorted out. Thank you for the SAL/HA changes in this PR. I appreciate you taking the time to review as well! |
Add SAL updates and topographic wave drag schemes for barotropic tides This PR incorporates updates to the global tidal forcing in MPAS-Ocean. It combines two contributions developed under the ICoM project: * @dengwirda's modifications to a) include surface pressure in the self attraction and loading (SAL) calculations b) use a depth rather than distance-based criteria in the SAL coastal smoothing factor, and c) update the harmonic analysis AM to account for initial SSH offsets. * @knbarton's refactoring of the existing Jayne and St. Laurent topographic wave drag (TWD) parameterization and the addition of the Zaron and Egbert and Local Generation Formula TWD schemes. [NML] [BFB] - mpas-ocean standalone
|
Passes:
with expected NML DIFFs. Merged to next |
|
merged to master and expected NML DIFFs blessed |
|
Thanks very much, @jonbob! |
|
A reminder that it is always a good idea to check the compass |
|
@xylar, I looked into this and wanted to note that the issue is in the namelist settings for the |
|
@sbrus89, as we discussed, that's great and quite a relief! |
| ! Enforce minimum depth | ||
| bottomDepth(iCell) = max(bottomDepthObserved(iCell), refBottomDepth(minimum_levels)) | ||
| bottomDepth(iCell) = max(bottomDepthObserved(iCell), config_global_ocean_minimum_depth) | ||
| bottomDepth(iCell) = min(bottomDepth(iCell), refBottomDepth(minimum_levels)) |
There was a problem hiding this comment.
This should have been a max, not a min.
There was a problem hiding this comment.
Thanks for fixing this @xylar! Sorry I overlooked this change and didn't catch it earlier.
A bug was introduced in E3SM-Project#6310 that made the ocean shallower rather than deeper than the minimum allowed depth. This merge fixes that bug.
This merge updates the E3SM-Project submodule from [31e0924](https://github.com/E3SM-Project/E3SM/tree/31e0924) to [8939709](https://github.com/E3SM-Project/E3SM/tree/8939709). This update includes the following MPAS-Ocean and MPAS-Frameworks PRs (check mark indicates bit-for-bit with previous PR in the list): - [ ] (ocn) E3SM-Project/E3SM#6263 - [ ] (ocn) E3SM-Project/E3SM#6310 - [ ] (fwk) E3SM-Project/E3SM#6427 - [ ] (ocn) E3SM-Project/E3SM#6397 - [ ] (ocn) E3SM-Project/E3SM#6306 - [ ] (ocn) E3SM-Project/E3SM#6454
…(PR #6471) Fix OpenACC deletes for topographic wave drag Partially addresses #6470 The errors were introduced in #6310, when variables were introduced and renamed, including in the OpenACC create directives but corresponding changes were incomplete for the OpenACC directives for deleting them. [BFB]



This PR incorporates updates to the global tidal forcing in MPAS-Ocean. It combines two contributions developed under the ICoM project:
This PR has been tested using a new compass case, which performs a 125-day tidal run (with a 90 day analysis period) on the VR45to5 mesh using the Zaron and Egbert topographic wave drag option. This results in a 3.3 cm M2 deep water RMSE as compared to the TPXO9 tidal database, which is the most accurate MPAS-Ocean tidal result to date. Here is a link to the compass PR with testing results: MPAS-Dev/compass#802
[NML]
[BFB] - mpas-ocean standalone