Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ca20f34
Only perform remap at beg of outer loop
cbegeman Mar 20, 2025
cc5d538
Remap layerThicknessCur before assigned to layerThicknessNew in SSE prep
cbegeman Apr 24, 2025
bcb2f1a
Assign new to cur at beg se
cbegeman Apr 4, 2025
748bbd0
Use layerThicknessLag for remap, add timeLevel argument
cbegeman Apr 1, 2025
324dbd5
Use existing ALE routine to determine layerThicknessTarget for remapping
cbegeman Apr 1, 2025
770b73b
Use timeLevel, nCellsAll, nEdgesAll in remap
cbegeman Apr 22, 2025
38552cb
Store remap old and new layerThicknesses in Lag and Target variables
cbegeman Apr 24, 2025
f91fe67
Use diagnostic variable for ALE_thickness
cbegeman Apr 22, 2025
9509adf
Use layerThicknessTarget for vertical velocity solve
cbegeman May 7, 2025
0293ad2
Set layerThicknessLagCur=layerThicknessCur before remap
cbegeman Apr 24, 2025
fd5eb04
Reorder remap calls for split integrator
cbegeman Apr 28, 2025
8cf7cbb
Reorder remap calls for semi-implicit integrator
cbegeman Apr 28, 2025
049cbae
Move remap back to end of time step where it remaps the new time level
cbegeman Aug 13, 2025
c0819f6
Use nCellsAll in thick ALE and vertVelocityTop
cbegeman May 1, 2025
7727e9d
Remove validate state calls bracketing remap
cbegeman May 6, 2025
46b0a5e
Remove additional SSH consistency check
cbegeman Jul 13, 2025
bf58df8
Fix number of arguments to ocn_ALE_thickness
cbegeman Jul 13, 2025
7414d59
Add coupled VLR tests
cbegeman Aug 1, 2025
597b2ed
Update layerThickEdgeFlux after remap
cbegeman Aug 12, 2025
b3998fc
WIP Allow flux through interfaces with remap equal to normalTransport…
cbegeman Aug 13, 2025
d960db4
Only assign layerThicknessLag in remap routine; probably only need on…
cbegeman Aug 13, 2025
8298a7b
BFB clean-up of remap
cbegeman Aug 14, 2025
5d6a146
Revert overwrite of vertVelocityTop
cbegeman Aug 15, 2025
1e00cc6
Manually shift layerThicknessLag time levels
cbegeman Aug 15, 2025
d73fda7
WIP fix layerInterfaceVelocity and reorg diagnostics routines
cbegeman Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cime_config/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@
"e3sm_ocnice_stealth_features" : {
"tests" : (
"SMS_D_Ld1.T62_oQU240wLI.GMPAS-IAF-PISMF.mpaso-impl_top_drag",
"SMS_D_Ld1.T62_oQU240wLI.GMPAS-IAF-PISMF.mpaso-vertical_remap",
"SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-harmonic_mean_drag",
"SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-vertical_remap",
"SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-upwind_advection",
"SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-freshwater_tracers",
"ERS_Ld5_D.T62_oQU240.GMPAS-IAF.mpaso-conservation_check",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test vertical Lagrangian-remapping capability with a remapping interval of every third timestep.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config_vert_advection_method = 'remap'
config_vert_remap_interval = 3
5 changes: 4 additions & 1 deletion components/mpas-ocean/src/Registry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3095,7 +3095,7 @@
packages="forwardMode;analysisMode"
/>
<var name="vertVelocityTop" type="real" dimensions="nVertLevelsP1 nCells Time" units="m s^-1"
description="vertical velocity defined at center (horizontally) and top (vertically) of cell"
description="vertical velocity defined at center (horizontally) and top (vertically) of cell. This is not the vertical ALE transport, but is Eulerian (fixed-frame) in the vertical, and computed from the continuity equation from the horizontal velocity."
packages="forwardMode;analysisMode"
/>
<var name="vertTransportVelocityTop" type="real" dimensions="nVertLevelsP1 nCells Time" units="m s^-1"
Expand All @@ -3111,6 +3111,9 @@
description="vertical tracer-transport velocity defined at center (horizontally) and top (vertically) of cell. This is not the vertical ALE transport, but is Eulerian (fixed-frame) in the vertical, and computed from the continuity equation from the horizontal MLE (submesoscale) Bolus velocity."
packages="submeso"
/>
<var name="layerThicknessTarget" type="real" dimensions="nVertLevels nCells Time" units="m"
description="The layerThickness from ALE routine, prior to remapping."
/>
<var name="tangentialVelocity" type="real" dimensions="nVertLevels nEdges Time" units="m s^-1"
description="horizontal velocity, tangential to an edge"
missing_value="FILLVAL" missing_value_mask="edgeMask"
Expand Down
221 changes: 167 additions & 54 deletions components/mpas-ocean/src/mode_forward/mpas_ocn_time_integration_rk4.F

Large diffs are not rendered by default.

144 changes: 104 additions & 40 deletions components/mpas-ocean/src/mode_forward/mpas_ocn_time_integration_si.F
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,11 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{
fluxAx

real (kind=RKIND), dimension(:,:), allocatable:: &
uTemp
div_hu, div_hu_tr, uTemp, layerInterfaceVelocity

real (kind=RKIND), dimension(:), allocatable :: &
btrvel_temp, &
projectedSSH, projectedSSH_tr, & ! SSH used to determine layerInterfaceVelocity
bottomDepthEdge

! State Array Pointers
Expand Down Expand Up @@ -384,7 +385,7 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{

! Remap variables
real (kind=RKIND), dimension(:,:), pointer :: &
layerThicknessLagNew
layerThicknessLagCur, layerThicknessLagNew

integer :: &
siLargeIter ! Index of the large btr system iteration
Expand Down Expand Up @@ -477,6 +478,9 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{
call mpas_pool_get_array(statePool, 'layerThickness', &
layerThicknessNew, 2)

call mpas_pool_get_array(statePool, 'layerThicknessLag', layerThicknessLagCur, 1)
call mpas_pool_get_array(statePool, 'layerThicknessLag', layerThicknessLagNew, 2)

call mpas_pool_get_array(statePool, 'highFreqThickness', &
highFreqThicknessCur, 1)
call mpas_pool_get_array(statePool, 'highFreqThickness', &
Expand Down Expand Up @@ -540,6 +544,29 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{

#endif

if ( configVertAdvMethod == vertAdvRemap ) then
if ( associated(layerThicknessLagCur) ) then
#ifdef MPAS_OPENACC
!$acc loop collapse(2)
#else
!$omp do schedule(runtime) private(k)
#endif
do iCell= 1,nCellsAll
do k = 1,nVertLevels
! Store the current, Lagrangian location for computation of the
! Eulerian vertical velocity induced by remapping
layerThicknessLagCur(k,iCell) = layerThicknessCur(k,iCell)
end do
end do
#ifndef MPAS_OPENACC
!$omp end do
#endif
endif
! Perform the remapping
! The updated layerThickness goes in layerThicknessCur which is assigned to layerThicknessNew below
call ocn_remap_vert_state(block, err, 1)
end if

! Initialize * variables that are used to compute baroclinic
! tendencies below.

Expand Down Expand Up @@ -828,16 +855,28 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{
! compute vertAleTransportTop. Use u (rather than &
! normalTransportVelocity) for momentum advection.
! Use the most recent time level available.

if (associated(highFreqThicknessNew)) then
call ocn_vert_transport_velocity_top( &
verticalMeshPool, layerThicknessCur, &
layerThickEdgeFlux, normalVelocityCur, sshCur, dt, &
vertAleTransportTop, err, highFreqThicknessNew)
! The diagnostic variable layerThicknessTarget is updated
allocate(layerInterfaceVelocity(nVertLevels, nCellsAll), &
div_hu(nVertLevels, nCellsAll), &
projectedSSH(nCellsAll))
#ifdef MPAS_OPENACC
!$acc enter data create(projectedSSH, div_hu)
#endif
call ocn_diagnostic_solve_divergence_hu(sshCur, layerThickEdgeFlux, &
normalVelocityCur, dt, div_hu, projectedSSH)
if ( configVertAdvMethod == vertAdvRemap ) then
vertAleTransportTop = 0.0_RKIND
else
call ocn_vert_transport_velocity_top( &
verticalMeshPool, layerThicknessCur, &
layerThickEdgeFlux, normalVelocityCur, sshCur, dt, &
if (associated(highFreqThicknessNew)) then
call ocn_layer_interface_velocity(verticalMeshPool, &
projectedSSH, layerThicknessCur, &
dt, layerInterfaceVelocity, err, highFreqThicknessNew)
else
call ocn_layer_interface_velocity(verticalMeshPool, &
projectedSSH, layerThicknessCur, &
dt, layerInterfaceVelocity, err)
endif
call ocn_vert_transport_velocity_top(div_hu, layerInterfaceVelocity, &
vertAleTransportTop, err)
endif

Expand Down Expand Up @@ -2127,27 +2166,51 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{
!$acc enter data copyin(layerThicknessCur, sshCur)
!$acc update device(layerThickEdgeFlux, normalTransportVelocity)
#endif
if (associated(highFreqThicknessNew)) then
allocate(div_hu_tr(nVertLevels, nCellsAll), &
projectedSSH_tr(nCellsAll))
#ifdef MPAS_OPENACC
!$acc enter data copyin(highFreqThicknessNew)
!$acc enter data create(projectedSSH_tr, div_hu_tr)
#endif
call ocn_vert_transport_velocity_top( &
verticalMeshPool, layerThicknessCur, &
layerThickEdgeFlux, normalTransportVelocity, sshCur, &
dt, vertAleTransportTop, err, highFreqThicknessNew)
call ocn_diagnostic_solve_divergence_hu(sshCur, layerThickEdgeFlux, &
normalTransportVelocity, dt, div_hu_tr, projectedSSH_tr)
if ( configVertAdvMethod == vertAdvRemap ) then
! This is the layerInterfaceVelocity implicit in w=0 during Stage 1
!$omp parallel
!$omp do schedule(runtime) &
!$omp private(k)
do iCell = 1, nCellsAll
do k = minLevelCell(iCell), maxLevelCell(iCell)
layerInterfaceVelocity(k,iCell) = div_hu(k,iCell)
enddo
enddo
!$omp end do
!$omp end parallel
else
if (associated(highFreqThicknessNew)) then
#ifdef MPAS_OPENACC
!$acc exit data delete(highFreqThicknessNew)
!$acc enter data copyin(highFreqThicknessNew)
#endif
else
call ocn_vert_transport_velocity_top( &
verticalMeshPool, layerThicknessCur, &
layerThickEdgeFlux, normalTransportVelocity, sshCur, &
dt, vertAleTransportTop, err)
call ocn_layer_interface_velocity(verticalMeshPool, &
projectedSSH_tr, layerThicknessCur, &
dt, layerInterfaceVelocity, err, highFreqThicknessNew)
#ifdef MPAS_OPENACC
!$acc exit data delete(highFreqThicknessNew)
#endif
else
call ocn_layer_interface_velocity(verticalMeshPool, &
projectedSSH_tr, layerThicknessCur, &
dt, layerInterfaceVelocity, err)
endif
endif
call ocn_vert_transport_velocity_top(div_hu_tr, layerInterfaceVelocity, &
vertAleTransportTop, err)
#ifdef MPAS_OPENACC
!$acc exit data delete(layerThicknessCur, sshCur)
!$acc exit data delete(projectedSSH_tr, div_hu)
!$acc update host(vertAleTransportTop, normalTransportVelocity)
#endif
deallocate(layerInterfaceVelocity, div_hu, projectedSSH)
deallocate(div_hu_tr, projectedSSH_tr)
call mpas_timer_stop('thick vert trans vel top')

call ocn_tend_thick(tendPool, forcingPool)
Expand Down Expand Up @@ -2420,6 +2483,24 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{
!$omp end parallel
#endif

if ( associated(layerThicknessLagNew) ) then
#ifdef MPAS_OPENACC
!$acc loop collapse(2)
#else
!$omp do schedule(runtime) private(k)
#endif
do iCell= 1,nCellsAll
do k = 1,nVertLevels
! Store the current, Lagrangian location for computation of the
! Eulerian vertical velocity induced by remapping
layerThicknessLagNew(k,iCell) = layerThicknessLagCur(k,iCell)
end do
end do
#ifndef MPAS_OPENACC
!$omp end do
#endif
endif

if (config_compute_active_tracer_budgets) then

#ifdef MPAS_OPENACC
Expand Down Expand Up @@ -2946,23 +3027,6 @@ subroutine ocn_time_integrator_si(domain, dt)!{{{

call mpas_timer_stop("si implicit vert mix")

if ( configVertAdvMethod == vertAdvRemap ) then

call mpas_timer_start("vertical remap")

call mpas_pool_get_array(statePool, 'layerThicknessLag', layerThicknessLagNew, 2)

! Store the current, Lagrangian location for computation of the
! Eulerian vertical velocity induced by remapping
layerThicknessLagNew = layerThicknessNew

! Perform the remapping
call ocn_remap_vert_state(block, err)

call mpas_timer_stop("vertical remap")

end if

call mpas_timer_start('si fini')

#ifdef MPAS_OPENACC
Expand Down
Loading