MOM6
mom_ale Module Reference

Detailed Description

This module contains the main regridding routines.

Regridding comprises two steps:

  1. Interpolation and creation of a new grid based on target interface densities (or any other criterion).
  2. Remapping of quantities between old grid and new grid.

Original module written by Laurent White, 2008.06.09

Data Types

type  ale_cs
 ALE control structure. More...
 

Functions/Subroutines

subroutine, public ale_init (param_file, GV, US, max_depth, CS)
 This routine is typically called (from initialize_MOM in file MOM.F90) before the main time integration loop to initialize the regridding stuff. We read the MOM_input file to register the values of different regridding/remapping parameters. More...
 
subroutine, public ale_register_diags (Time, G, GV, US, diag, CS)
 Initialize diagnostics for the ALE module. More...
 
subroutine, public adjustgridforintegrity (CS, G, GV, h)
 Crudely adjust (initial) grid for integrity. This routine is typically called (from initialize_MOM in file MOM.F90) before the main time integration loop to initialize the regridding stuff. We read the MOM_input file to register the values of different regridding/remapping parameters. More...
 
subroutine, public ale_end (CS)
 End of regridding (memory deallocation). This routine is typically called (from MOM_end in file MOM.F90) after the main time integration loop to deallocate the regridding stuff. More...
 
subroutine, public ale_main (G, GV, US, h, u, v, tv, Reg, CS, dt, frac_shelf_h)
 Takes care of (1) building a new grid and (2) remapping all variables between the old grid and the new grid. The creation of the new grid can be based on z coordinates, target interface densities, sigma coordinates or any arbitrary coordinate system. More...
 
subroutine, public ale_main_offline (G, GV, h, tv, Reg, CS, dt)
 Takes care of (1) building a new grid and (2) remapping all variables between the old grid and the new grid. The creation of the new grid can be based on z coordinates, target interface densities, sigma coordinates or any arbitrary coordinate system. More...
 
subroutine, public ale_offline_inputs (CS, G, GV, h, tv, Reg, uhtr, vhtr, Kd, debug)
 Regrid/remap stored fields used for offline tracer integrations. These input fields are assumed to have the same layer thicknesses at the end of the last offline interval (which should be a Zstar grid). This routine builds a grid on the runtime specified vertical coordinate. More...
 
subroutine, public ale_offline_tracer_final (G, GV, h, tv, h_target, Reg, CS)
 Remaps all tracers from h onto h_target. This is intended to be called when tracers are done offline. In the case where transports don't quite conserve, we still want to make sure that layer thicknesses offline do not drift too far away from the online model. More...
 
subroutine check_grid (G, GV, h, threshold)
 Check grid for negative thicknesses. More...
 
subroutine, public ale_build_grid (G, GV, regridCS, remapCS, h, tv, debug, frac_shelf_h)
 Generates new grid. More...
 
subroutine, public ale_regrid_accelerated (CS, G, GV, h, tv, n, u, v, Reg, dt, dzRegrid, initial)
 For a state-based coordinate, accelerate the process of regridding by repeatedly applying the grid calculation algorithm. More...
 
subroutine remap_all_state_vars (CS_remapping, CS_ALE, G, GV, h_old, h_new, Reg, dxInterface, u, v, debug, dt)
 This routine takes care of remapping all variable between the old and the new grids. When velocity components need to be remapped, thicknesses at velocity points are taken to be arithmetic averages of tracer thicknesses. This routine is called during initialization of the model at time=0, to remap initiali conditions to the model grid. It is also called during a time step to update the state. More...
 
subroutine, public ale_remap_scalar (CS, G, GV, nk_src, h_src, s_src, h_dst, s_dst, all_cells, old_remap)
 Remaps a single scalar between grids described by thicknesses h_src and h_dst. h_dst must be dimensioned as a model array with GVke layers while h_src can have an arbitrary number of layers specified by nk_src. More...
 
subroutine, public pressure_gradient_plm (CS, S_t, S_b, T_t, T_b, G, GV, tv, h, bdry_extrap)
 Use plm reconstruction for pressure gradient (determine edge values) By using a PLM (limited piecewise linear method) reconstruction, this routine determines the edge values for the salinity and temperature within each layer. These edge values are returned and are used to compute the pressure gradient (by computing the densities). More...
 
subroutine, public pressure_gradient_ppm (CS, S_t, S_b, T_t, T_b, G, GV, tv, h, bdry_extrap)
 Use ppm reconstruction for pressure gradient (determine edge values) By using a PPM (limited piecewise linear method) reconstruction, this routine determines the edge values for the salinity and temperature within each layer. These edge values are returned and are used to compute the pressure gradient (by computing the densities). More...
 
subroutine, public ale_initregridding (GV, US, max_depth, param_file, mdl, regridCS)
 Initializes regridding for the main ALE algorithm. More...
 
real function, dimension(cs%nk+1), public ale_getcoordinate (CS)
 Query the target coordinate interfaces positions. More...
 
character(len=20) function, public ale_getcoordinateunits (CS)
 Query the target coordinate units. More...
 
logical function, public ale_remap_init_conds (CS)
 Returns true if initial conditions should be regridded and remapped. More...
 
subroutine, public ale_update_regrid_weights (dt, CS)
 Updates the weights for time filtering the new grid generated in regridding. More...
 
subroutine, public ale_updateverticalgridtype (CS, GV)
 Update the vertical grid type with ALE information. This subroutine sets information in the verticalGrid_type to be consistent with the use of ALE mode. More...
 
subroutine, public ale_writecoordinatefile (CS, GV, directory)
 Write the vertical coordinate information into a file. This subroutine writes out a file containing any available data related to the vertical grid used by the MOM ocean model when in ALE mode. More...
 
subroutine, public ale_initthicknesstocoord (CS, G, GV, h)
 Set h to coordinate values for fixed coordinate systems. More...
 

Function/Subroutine Documentation

◆ adjustgridforintegrity()

subroutine, public mom_ale::adjustgridforintegrity ( type(ale_cs), pointer  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  h 
)

Crudely adjust (initial) grid for integrity. This routine is typically called (from initialize_MOM in file MOM.F90) before the main time integration loop to initialize the regridding stuff. We read the MOM_input file to register the values of different regridding/remapping parameters.

Parameters
csRegridding parameters and options
[in]gOcean grid informations
[in]gvOcean vertical grid structure
[in,out]hCurrent 3D grid thickness that are to be adjusted [H ~> m or kg-2]

Definition at line 276 of file MOM_ALE.F90.

276  type(ALE_CS), pointer :: CS !< Regridding parameters and options
277  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
278  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
279  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid thickness that
280  !! are to be adjusted [H ~> m or kg-2]
281  call inflate_vanished_layers_old( cs%regridCS, g, gv, h(:,:,:) )
282 

◆ ale_build_grid()

subroutine, public mom_ale::ale_build_grid ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(regridding_cs), intent(in)  regridCS,
type(remapping_cs), intent(in)  remapCS,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv,
logical, intent(in), optional  debug,
real, dimension(:,:), optional, pointer  frac_shelf_h 
)

Generates new grid.

Parameters
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in]regridcsRegridding parameters and options
[in]remapcsRemapping parameters and options
[in,out]tvThermodynamical variable structure
[in,out]hCurrent 3D grid obtained after the last time step [H ~> m or kg-2]
[in]debugIf true, show the call tree
frac_shelf_hFractional ice shelf coverage

Definition at line 594 of file MOM_ALE.F90.

594  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
595  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
596  type(regridding_CS), intent(in) :: regridCS !< Regridding parameters and options
597  type(remapping_CS), intent(in) :: remapCS !< Remapping parameters and options
598  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamical variable structure
599  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the
600  !! last time step [H ~> m or kg-2]
601  logical, optional, intent(in) :: debug !< If true, show the call tree
602  real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage
603  ! Local variables
604  integer :: nk, i, j, k
605  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
606  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new ! The new grid thicknesses
607  logical :: show_call_tree, use_ice_shelf
608 
609  show_call_tree = .false.
610  if (present(debug)) show_call_tree = debug
611  if (show_call_tree) call calltree_enter("ALE_build_grid(), MOM_ALE.F90")
612  use_ice_shelf = .false.
613  if (present(frac_shelf_h)) then
614  if (associated(frac_shelf_h)) use_ice_shelf = .true.
615  endif
616 
617  ! Build new grid. The new grid is stored in h_new. The old grid is h.
618  ! Both are needed for the subsequent remapping of variables.
619  if (use_ice_shelf) then
620  call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid, frac_shelf_h )
621  else
622  call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid )
623  endif
624 
625  ! Override old grid with new one. The new grid 'h_new' is built in
626  ! one of the 'build_...' routines above.
627 !$OMP parallel do default(none) shared(G,h,h_new)
628  do j = g%jsc,g%jec ; do i = g%isc,g%iec
629  if (g%mask2dT(i,j)>0.) h(i,j,:) = h_new(i,j,:)
630  enddo ; enddo
631 
632  if (show_call_tree) call calltree_leave("ALE_build_grid()")

◆ ale_end()

subroutine, public mom_ale::ale_end ( type(ale_cs), pointer  CS)

End of regridding (memory deallocation). This routine is typically called (from MOM_end in file MOM.F90) after the main time integration loop to deallocate the regridding stuff.

Parameters
csmodule control structure

Definition at line 290 of file MOM_ALE.F90.

290  type(ALE_CS), pointer :: CS !< module control structure
291 
292  ! Deallocate memory used for the regridding
293  call end_remapping( cs%remapCS )
294  call end_regridding( cs%regridCS )
295 
296  deallocate(cs)
297 

◆ ale_getcoordinate()

real function, dimension(cs%nk+1), public mom_ale::ale_getcoordinate ( type(ale_cs), pointer  CS)

Query the target coordinate interfaces positions.

Parameters
csmodule control structure

Definition at line 1135 of file MOM_ALE.F90.

1135  type(ALE_CS), pointer :: CS !< module control structure
1136 
1137  real, dimension(CS%nk+1) :: ALE_getCoordinate
1138  ale_getcoordinate(:) = getcoordinateinterfaces( cs%regridCS, undo_scaling=.true. )
1139 

◆ ale_getcoordinateunits()

character(len=20) function, public mom_ale::ale_getcoordinateunits ( type(ale_cs), pointer  CS)

Query the target coordinate units.

Parameters
csmodule control structure

Definition at line 1145 of file MOM_ALE.F90.

1145  type(ALE_CS), pointer :: CS !< module control structure
1146 
1147  character(len=20) :: ALE_getCoordinateUnits
1148 
1149  ale_getcoordinateunits = getcoordinateunits( cs%regridCS )
1150 

◆ ale_init()

subroutine, public mom_ale::ale_init ( type(param_file_type), intent(in)  param_file,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
real, intent(in)  max_depth,
type(ale_cs), pointer  CS 
)

This routine is typically called (from initialize_MOM in file MOM.F90) before the main time integration loop to initialize the regridding stuff. We read the MOM_input file to register the values of different regridding/remapping parameters.

Parameters
[in]param_fileParameter file
[in]gvOcean vertical grid structure
[in]usA dimensional unit scaling type
[in]max_depthThe maximum depth of the ocean [Z ~> m].
csModule control structure

Definition at line 135 of file MOM_ALE.F90.

135  type(param_file_type), intent(in) :: param_file !< Parameter file
136  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
137  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
138  real, intent(in) :: max_depth !< The maximum depth of the ocean [Z ~> m].
139  type(ALE_CS), pointer :: CS !< Module control structure
140 
141  ! Local variables
142  real, dimension(:), allocatable :: dz
143  character(len=40) :: mdl = "MOM_ALE" ! This module's name.
144  character(len=80) :: string ! Temporary strings
145  real :: filter_shallow_depth, filter_deep_depth
146  logical :: check_reconstruction
147  logical :: check_remapping
148  logical :: force_bounds_in_subcell
149  logical :: local_logical
150  logical :: remap_boundary_extrap
151 
152  if (associated(cs)) then
153  call mom_error(warning, "ALE_init called with an associated "// &
154  "control structure.")
155  return
156  endif
157  allocate(cs)
158 
159  cs%show_call_tree = calltree_showquery()
160  if (cs%show_call_tree) call calltree_enter("ALE_init(), MOM_ALE.F90")
161 
162  call get_param(param_file, mdl, "REMAP_UV_USING_OLD_ALG", &
163  cs%remap_uv_using_old_alg, &
164  "If true, uses the old remapping-via-a-delta-z method for "//&
165  "remapping u and v. If false, uses the new method that remaps "//&
166  "between grids described by an old and new thickness.", &
167  default=.true.)
168 
169  ! Initialize and configure regridding
170  call ale_initregridding(gv, us, max_depth, param_file, mdl, cs%regridCS)
171 
172  ! Initialize and configure remapping
173  call get_param(param_file, mdl, "REMAPPING_SCHEME", string, &
174  "This sets the reconstruction scheme used "//&
175  "for vertical remapping for all variables. "//&
176  "It can be one of the following schemes: "//&
177  trim(remappingschemesdoc), default=remappingdefaultscheme)
178  call get_param(param_file, mdl, "FATAL_CHECK_RECONSTRUCTIONS", check_reconstruction, &
179  "If true, cell-by-cell reconstructions are checked for "//&
180  "consistency and if non-monotonicity or an inconsistency is "//&
181  "detected then a FATAL error is issued.", default=.false.)
182  call get_param(param_file, mdl, "FATAL_CHECK_REMAPPING", check_remapping, &
183  "If true, the results of remapping are checked for "//&
184  "conservation and new extrema and if an inconsistency is "//&
185  "detected then a FATAL error is issued.", default=.false.)
186  call get_param(param_file, mdl, "REMAP_BOUND_INTERMEDIATE_VALUES", force_bounds_in_subcell, &
187  "If true, the values on the intermediate grid used for remapping "//&
188  "are forced to be bounded, which might not be the case due to "//&
189  "round off.", default=.false.)
190  call get_param(param_file, mdl, "REMAP_BOUNDARY_EXTRAP", remap_boundary_extrap, &
191  "If true, values at the interfaces of boundary cells are "//&
192  "extrapolated instead of piecewise constant", default=.false.)
193  call initialize_remapping( cs%remapCS, string, &
194  boundary_extrapolation=remap_boundary_extrap, &
195  check_reconstruction=check_reconstruction, &
196  check_remapping=check_remapping, &
197  force_bounds_in_subcell=force_bounds_in_subcell)
198 
199  call get_param(param_file, mdl, "REMAP_AFTER_INITIALIZATION", cs%remap_after_initialization, &
200  "If true, applies regridding and remapping immediately after "//&
201  "initialization so that the state is ALE consistent. This is a "//&
202  "legacy step and should not be needed if the initialization is "//&
203  "consistent with the coordinate mode.", default=.true.)
204 
205  call get_param(param_file, mdl, "REGRID_TIME_SCALE", cs%regrid_time_scale, &
206  "The time-scale used in blending between the current (old) grid "//&
207  "and the target (new) grid. A short time-scale favors the target "//&
208  "grid (0. or anything less than DT_THERM) has no memory of the old "//&
209  "grid. A very long time-scale makes the model more Lagrangian.", &
210  units="s", default=0.)
211  call get_param(param_file, mdl, "REGRID_FILTER_SHALLOW_DEPTH", filter_shallow_depth, &
212  "The depth above which no time-filtering is applied. Above this depth "//&
213  "final grid exactly matches the target (new) grid.", &
214  units="m", default=0., scale=gv%m_to_H)
215  call get_param(param_file, mdl, "REGRID_FILTER_DEEP_DEPTH", filter_deep_depth, &
216  "The depth below which full time-filtering is applied with time-scale "//&
217  "REGRID_TIME_SCALE. Between depths REGRID_FILTER_SHALLOW_DEPTH and "//&
218  "REGRID_FILTER_SHALLOW_DEPTH the filter weights adopt a cubic profile.", &
219  units="m", default=0., scale=gv%m_to_H)
220  call set_regrid_params(cs%regridCS, depth_of_time_filter_shallow=filter_shallow_depth, &
221  depth_of_time_filter_deep=filter_deep_depth)
222  call get_param(param_file, mdl, "REGRID_USE_OLD_DIRECTION", local_logical, &
223  "If true, the regridding ntegrates upwards from the bottom for "//&
224  "interface positions, much as the main model does. If false "//&
225  "regridding integrates downward, consistant with the remapping "//&
226  "code.", default=.true., do_not_log=.true.)
227  call set_regrid_params(cs%regridCS, integrate_downward_for_e=.not.local_logical)
228 
229  ! Keep a record of values for subsequent queries
230  cs%nk = gv%ke
231 
232  if (cs%show_call_tree) call calltree_leave("ALE_init()")

◆ ale_initregridding()

subroutine, public mom_ale::ale_initregridding ( type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
real, intent(in)  max_depth,
type(param_file_type), intent(in)  param_file,
character(len=*), intent(in)  mdl,
type(regridding_cs), intent(out)  regridCS 
)

Initializes regridding for the main ALE algorithm.

Parameters
[in]gvOcean vertical grid structure
[in]usA dimensional unit scaling type
[in]max_depthThe maximum depth of the ocean [Z ~> m].
[in]param_fileparameter file
[in]mdlName of calling module
[out]regridcsRegridding parameters and work arrays

Definition at line 1114 of file MOM_ALE.F90.

1114  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
1115  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
1116  real, intent(in) :: max_depth !< The maximum depth of the ocean [Z ~> m].
1117  type(param_file_type), intent(in) :: param_file !< parameter file
1118  character(len=*), intent(in) :: mdl !< Name of calling module
1119  type(regridding_CS), intent(out) :: regridCS !< Regridding parameters and work arrays
1120  ! Local variables
1121  character(len=30) :: coord_mode
1122 
1123  call get_param(param_file, mdl, "REGRIDDING_COORDINATE_MODE", coord_mode, &
1124  "Coordinate mode for vertical regridding. "//&
1125  "Choose among the following possibilities: "//&
1126  trim(regriddingcoordinatemodedoc), &
1127  default=default_coordinate_mode, fail_if_missing=.true.)
1128 
1129  call initialize_regridding(regridcs, gv, us, max_depth, param_file, mdl, coord_mode, '', '')
1130 

◆ ale_initthicknesstocoord()

subroutine, public mom_ale::ale_initthicknesstocoord ( type(ale_cs), intent(inout)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(out)  h 
)

Set h to coordinate values for fixed coordinate systems.

Parameters
[in,out]csmodule control structure
[in]gmodule grid structure
[in]gvOcean vertical grid structure
[out]hlayer thickness [H ~> m or kg m-2]

Definition at line 1234 of file MOM_ALE.F90.

1234  type(ALE_CS), intent(inout) :: CS !< module control structure
1235  type(ocean_grid_type), intent(in) :: G !< module grid structure
1236  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
1237  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: h !< layer thickness [H ~> m or kg m-2]
1238 
1239  ! Local variables
1240  integer :: i, j, k
1241 
1242  do j = g%jsd,g%jed ; do i = g%isd,g%ied
1243  h(i,j,:) = gv%Z_to_H * getstaticthickness( cs%regridCS, 0., g%bathyT(i,j) )
1244  enddo ; enddo
1245 

◆ ale_main()

subroutine, public mom_ale::ale_main ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  h,
real, dimension(szib_(g),szj_(g),szk_(gv)), intent(inout)  u,
real, dimension(szi_(g),szjb_(g),szk_(gv)), intent(inout)  v,
type(thermo_var_ptrs), intent(inout)  tv,
type(tracer_registry_type), pointer  Reg,
type(ale_cs), pointer  CS,
real, intent(in), optional  dt,
real, dimension(:,:), optional, pointer  frac_shelf_h 
)

Takes care of (1) building a new grid and (2) remapping all variables between the old grid and the new grid. The creation of the new grid can be based on z coordinates, target interface densities, sigma coordinates or any arbitrary coordinate system.

Parameters
[in]gOcean grid informations
[in]gvOcean vertical grid structure
[in]usA dimensional unit scaling type
[in,out]hCurrent 3D grid obtained after the last time step [H ~> m or kg m-2]
[in,out]uZonal velocity field [m s-1]
[in,out]vMeridional velocity field [m s-1]
[in,out]tvThermodynamic variable structure
regTracer registry structure
csRegridding parameters and options
[in]dtTime step between calls to ALE_main()
frac_shelf_hFractional ice shelf coverage

Definition at line 305 of file MOM_ALE.F90.

305  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
306  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
307  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
308  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the
309  !! last time step [H ~> m or kg m-2]
310  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: u !< Zonal velocity field [m s-1]
311  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: v !< Meridional velocity field [m s-1]
312  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
313  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
314  type(ALE_CS), pointer :: CS !< Regridding parameters and options
315  real, optional, intent(in) :: dt !< Time step between calls to ALE_main()
316  real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage
317  ! Local variables
318  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
319  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: eta_preale
320  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step [H ~> m or kg-2]
321  integer :: nk, i, j, k, isc, iec, jsc, jec
322  logical :: ice_shelf
323 
324  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
325 
326  ice_shelf = .false.
327  if (present(frac_shelf_h)) then
328  if (associated(frac_shelf_h)) ice_shelf = .true.
329  endif
330 
331  if (cs%show_call_tree) call calltree_enter("ALE_main(), MOM_ALE.F90")
332 
333  ! These diagnostics of the state before ALE is applied are mostly used for debugging.
334  if (cs%id_u_preale > 0) call post_data(cs%id_u_preale, u, cs%diag)
335  if (cs%id_v_preale > 0) call post_data(cs%id_v_preale, v, cs%diag)
336  if (cs%id_h_preale > 0) call post_data(cs%id_h_preale, h, cs%diag)
337  if (cs%id_T_preale > 0) call post_data(cs%id_T_preale, tv%T, cs%diag)
338  if (cs%id_S_preale > 0) call post_data(cs%id_S_preale, tv%S, cs%diag)
339  if (cs%id_e_preale > 0) then
340  call find_eta(h, tv, g, gv, us, eta_preale)
341  call post_data(cs%id_e_preale, eta_preale, cs%diag)
342  endif
343 
344  if (present(dt)) then
345  call ale_update_regrid_weights( dt, cs )
346  endif
347  dzregrid(:,:,:) = 0.0
348 
349  ! Build new grid. The new grid is stored in h_new. The old grid is h.
350  ! Both are needed for the subsequent remapping of variables.
351  if (ice_shelf) then
352  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, frac_shelf_h)
353  else
354  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid)
355  endif
356 
357  call check_grid( g, gv, h, 0. )
358 
359  if (cs%show_call_tree) call calltree_waypoint("new grid generated (ALE_main)")
360 
361  ! The presence of dt is used for expediency to distinguish whether ALE_main is being called during init
362  ! or in the main loop. Tendency diagnostics in remap_all_state_vars also rely on this logic.
363  if (present(dt)) then
364  call diag_update_remap_grids(cs%diag)
365  endif
366  ! Remap all variables from old grid h onto new grid h_new
367  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, -dzregrid, &
368  u, v, cs%show_call_tree, dt )
369 
370  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_main)")
371 
372  ! Override old grid with new one. The new grid 'h_new' is built in
373  ! one of the 'build_...' routines above.
374  !$OMP parallel do default(shared)
375  do k = 1,nk ; do j = jsc-1,jec+1 ; do i = isc-1,iec+1
376  h(i,j,k) = h_new(i,j,k)
377  enddo ; enddo ; enddo
378 
379  if (cs%show_call_tree) call calltree_leave("ALE_main()")
380 
381  if (cs%id_dzRegrid>0 .and. present(dt)) call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
382 
383 

◆ ale_main_offline()

subroutine, public mom_ale::ale_main_offline ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv,
type(tracer_registry_type), pointer  Reg,
type(ale_cs), pointer  CS,
real, intent(in), optional  dt 
)

Takes care of (1) building a new grid and (2) remapping all variables between the old grid and the new grid. The creation of the new grid can be based on z coordinates, target interface densities, sigma coordinates or any arbitrary coordinate system.

Parameters
[in]gOcean grid informations
[in]gvOcean vertical grid structure
[in,out]hCurrent 3D grid obtained after the last time step [H ~> m or kg-2]
[in,out]tvThermodynamic variable structure
regTracer registry structure
csRegridding parameters and options
[in]dtTime step between calls to ALE_main()

Definition at line 391 of file MOM_ALE.F90.

391  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
392  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
393  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the
394  !! last time step [H ~> m or kg-2]
395  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
396  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
397  type(ALE_CS), pointer :: CS !< Regridding parameters and options
398  real, optional, intent(in) :: dt !< Time step between calls to ALE_main()
399  ! Local variables
400  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
401  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step [H ~> m or kg-2]
402  integer :: nk, i, j, k, isc, iec, jsc, jec
403 
404  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
405 
406  if (cs%show_call_tree) call calltree_enter("ALE_main_offline(), MOM_ALE.F90")
407 
408  if (present(dt)) then
409  call ale_update_regrid_weights( dt, cs )
410  endif
411  dzregrid(:,:,:) = 0.0
412 
413  ! Build new grid. The new grid is stored in h_new. The old grid is h.
414  ! Both are needed for the subsequent remapping of variables.
415  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid )
416 
417  call check_grid( g, gv, h, 0. )
418 
419  if (cs%show_call_tree) call calltree_waypoint("new grid generated (ALE_main)")
420 
421  ! Remap all variables from old grid h onto new grid h_new
422 
423  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree, dt=dt )
424 
425  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_main)")
426 
427  ! Override old grid with new one. The new grid 'h_new' is built in
428  ! one of the 'build_...' routines above.
429  !$OMP parallel do default(shared)
430  do k = 1,nk ; do j = jsc-1,jec+1 ; do i = isc-1,iec+1
431  h(i,j,k) = h_new(i,j,k)
432  enddo ; enddo ; enddo
433 
434  if (cs%show_call_tree) call calltree_leave("ALE_main()")
435  if (cs%id_dzRegrid>0 .and. present(dt)) call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
436 

◆ ale_offline_inputs()

subroutine, public mom_ale::ale_offline_inputs ( type(ale_cs), pointer  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv,
type(tracer_registry_type), pointer  Reg,
real, dimension(szib_(g),szj_(g),szk_(gv)), intent(inout)  uhtr,
real, dimension(szi_(g),szjb_(g),szk_(gv)), intent(inout)  vhtr,
real, dimension(szi_(g),szj_(g),szk_(gv)+1), intent(inout)  Kd,
logical, intent(in)  debug 
)

Regrid/remap stored fields used for offline tracer integrations. These input fields are assumed to have the same layer thicknesses at the end of the last offline interval (which should be a Zstar grid). This routine builds a grid on the runtime specified vertical coordinate.

Parameters
csRegridding parameters and options
[in]gOcean grid informations
[in]gvOcean vertical grid structure
[in,out]hLayer thicknesses
[in,out]tvThermodynamic variable structure
regTracer registry structure
[in,out]uhtrZonal mass fluxes
[in,out]vhtrMeridional mass fluxes
[in,out]kdInput diffusivites
[in]debugIf true, then turn checksums

Definition at line 443 of file MOM_ALE.F90.

443  type(ALE_CS), pointer :: CS !< Regridding parameters and options
444  type(ocean_grid_type), intent(in ) :: G !< Ocean grid informations
445  type(verticalGrid_type), intent(in ) :: GV !< Ocean vertical grid structure
446  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Layer thicknesses
447  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
448  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
449  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr !< Zonal mass fluxes
450  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: vhtr !< Meridional mass fluxes
451  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: Kd !< Input diffusivites
452  logical, intent(in ) :: debug !< If true, then turn checksums
453  ! Local variables
454  integer :: nk, i, j, k, isc, iec, jsc, jec
455  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new ! Layer thicknesses after regridding
456  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
457  real, dimension(SZK_(GV)) :: h_src
458  real, dimension(SZK_(GV)) :: h_dest, uh_dest
459  real, dimension(SZK_(GV)) :: temp_vec
460 
461  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
462  dzregrid(:,:,:) = 0.0
463  h_new(:,:,:) = 0.0
464 
465  if (debug) call mom_tracer_chkinv("Before ALE_offline_inputs", g, h, reg%Tr, reg%ntr)
466 
467  ! Build new grid from the Zstar state onto the requested vertical coordinate. The new grid is stored
468  ! in h_new. The old grid is h. Both are needed for the subsequent remapping of variables. Convective
469  ! adjustment right now is not used because it is unclear what to do with vanished layers
470  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, conv_adjust = .false. )
471  call check_grid( g, gv, h_new, 0. )
472  if (cs%show_call_tree) call calltree_waypoint("new grid generated (ALE_offline_inputs)")
473 
474  ! Remap all variables from old grid h onto new grid h_new
475  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree )
476  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_inputs)")
477 
478  ! Reintegrate mass transports from Zstar to the offline vertical coordinate
479  do j=jsc,jec ; do i=g%iscB,g%iecB
480  if (g%mask2dCu(i,j)>0.) then
481  h_src(:) = 0.5 * (h(i,j,:) + h(i+1,j,:))
482  h_dest(:) = 0.5 * (h_new(i,j,:) + h_new(i+1,j,:))
483  call reintegrate_column(nk, h_src, uhtr(i,j,:), nk, h_dest, 0., temp_vec)
484  uhtr(i,j,:) = temp_vec
485  endif
486  enddo ; enddo
487  do j=g%jscB,g%jecB ; do i=isc,iec
488  if (g%mask2dCv(i,j)>0.) then
489  h_src(:) = 0.5 * (h(i,j,:) + h(i,j+1,:))
490  h_dest(:) = 0.5 * (h_new(i,j,:) + h_new(i,j+1,:))
491  call reintegrate_column(nk, h_src, vhtr(i,j,:), nk, h_dest, 0., temp_vec)
492  vhtr(i,j,:) = temp_vec
493  endif
494  enddo ; enddo
495 
496  do j = jsc,jec ; do i=isc,iec
497  if (g%mask2dT(i,j)>0.) then
498  if (check_column_integrals(nk, h_src, nk, h_dest)) then
499  call mom_error(fatal, "ALE_offline_inputs: Kd interpolation columns do not match")
500  endif
501  call interpolate_column(nk, h(i,j,:), kd(i,j,:), nk, h_new(i,j,:), 0., kd(i,j,:))
502  endif
503  enddo ; enddo
504 
505  call ale_remap_scalar(cs%remapCS, g, gv, nk, h, tv%T, h_new, tv%T)
506  call ale_remap_scalar(cs%remapCS, g, gv, nk, h, tv%S, h_new, tv%S)
507 
508  if (debug) call mom_tracer_chkinv("After ALE_offline_inputs", g, h_new, reg%Tr, reg%ntr)
509 
510  ! Copy over the new layer thicknesses
511  do k = 1,nk ; do j = jsc-1,jec+1 ; do i = isc-1,iec+1
512  h(i,j,k) = h_new(i,j,k)
513  enddo ; enddo ; enddo
514 
515  if (cs%show_call_tree) call calltree_leave("ALE_offline_inputs()")

◆ ale_offline_tracer_final()

subroutine, public mom_ale::ale_offline_tracer_final ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h_target,
type(tracer_registry_type), pointer  Reg,
type(ale_cs), pointer  CS 
)

Remaps all tracers from h onto h_target. This is intended to be called when tracers are done offline. In the case where transports don't quite conserve, we still want to make sure that layer thicknesses offline do not drift too far away from the online model.

Parameters
[in]gOcean grid informations
[in]gvOcean vertical grid structure
[in,out]hCurrent 3D grid obtained after the last time step [H ~> m or kg-2]
[in,out]tvThermodynamic variable structure
[in,out]h_targetCurrent 3D grid obtained after last time step [H ~> m or kg-2]
regTracer registry structure
csRegridding parameters and options

Definition at line 523 of file MOM_ALE.F90.

523  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
524  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
525  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the
526  !! last time step [H ~> m or kg-2]
527  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
528  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h_target !< Current 3D grid obtained after
529  !! last time step [H ~> m or kg-2]
530  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
531  type(ALE_CS), pointer :: CS !< Regridding parameters and options
532  ! Local variables
533 
534  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid !< The change in grid interface positions
535  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new !< Regridded target thicknesses
536  integer :: nk, i, j, k, isc, iec, jsc, jec
537 
538  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
539 
540  if (cs%show_call_tree) call calltree_enter("ALE_offline_tracer_final(), MOM_ALE.F90")
541  ! Need to make sure that h_target is consistent with the current offline ALE confiuration
542  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h_target, tv, h_new, dzregrid )
543  call check_grid( g, gv, h_target, 0. )
544 
545 
546  if (cs%show_call_tree) call calltree_waypoint("Source and target grids checked (ALE_offline_tracer_final)")
547 
548  ! Remap all variables from old grid h onto new grid h_new
549 
550  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree )
551 
552  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_offline_tracer_final)")
553 
554  ! Override old grid with new one. The new grid 'h_new' is built in
555  ! one of the 'build_...' routines above.
556  !$OMP parallel do default(shared)
557  do k = 1,nk
558  do j = jsc-1,jec+1 ; do i = isc-1,iec+1
559  h(i,j,k) = h_new(i,j,k)
560  enddo ; enddo
561  enddo
562  if (cs%show_call_tree) call calltree_leave("ALE_offline_tracer_final()")

◆ ale_register_diags()

subroutine, public mom_ale::ale_register_diags ( type(time_type), intent(in), target  Time,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(diag_ctrl), intent(in), target  diag,
type(ale_cs), pointer  CS 
)

Initialize diagnostics for the ALE module.

Parameters
[in]timeTime structure
[in]gGrid structure
[in]usA dimensional unit scaling type
[in]gvOcean vertical grid structure
[in]diagDiagnostics control structure
csModule control structure

Definition at line 237 of file MOM_ALE.F90.

237  type(time_type),target, intent(in) :: Time !< Time structure
238  type(ocean_grid_type), intent(in) :: G !< Grid structure
239  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
240  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
241  type(diag_ctrl), target, intent(in) :: diag !< Diagnostics control structure
242  type(ALE_CS), pointer :: CS !< Module control structure
243 
244  cs%diag => diag
245 
246  ! These diagnostics of the state variables before ALE are useful for
247  ! debugging the ALE code.
248  cs%id_u_preale = register_diag_field('ocean_model', 'u_preale', diag%axesCuL, time, &
249  'Zonal velocity before remapping', 'm s-1')
250  cs%id_v_preale = register_diag_field('ocean_model', 'v_preale', diag%axesCvL, time, &
251  'Meridional velocity before remapping', 'm s-1')
252  cs%id_h_preale = register_diag_field('ocean_model', 'h_preale', diag%axesTL, time, &
253  'Layer Thickness before remapping', get_thickness_units(gv), v_extensive=.true.)
254  cs%id_T_preale = register_diag_field('ocean_model', 'T_preale', diag%axesTL, time, &
255  'Temperature before remapping', 'degC')
256  cs%id_S_preale = register_diag_field('ocean_model', 'S_preale', diag%axesTL, time, &
257  'Salinity before remapping', 'PSU')
258  cs%id_e_preale = register_diag_field('ocean_model', 'e_preale', diag%axesTi, time, &
259  'Interface Heights before remapping', 'm', conversion=us%Z_to_m)
260 
261  cs%id_dzRegrid = register_diag_field('ocean_model','dzRegrid',diag%axesTi,time, &
262  'Change in interface height due to ALE regridding', 'm')
263  cs%id_vert_remap_h = register_diag_field('ocean_model','vert_remap_h',diag%axestl,time, &
264  'layer thicknesses after ALE regridding and remapping', 'm', v_extensive = .true.)
265  cs%id_vert_remap_h_tendency = register_diag_field('ocean_model','vert_remap_h_tendency',diag%axestl,time, &
266  'Layer thicknesses tendency due to ALE regridding and remapping', 'm', v_extensive = .true.)
267 

◆ ale_regrid_accelerated()

subroutine, public mom_ale::ale_regrid_accelerated ( type(ale_cs), pointer  CS,
type(ocean_grid_type), intent(inout)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv,
integer, intent(in)  n,
real, dimension( g %isdb: g %iedb, g %jsd: g %jed, gv %ke), intent(inout)  u,
real, dimension( g %isd: g %ied, g %jsdb: g %jedb, gv %ke), intent(inout)  v,
type(tracer_registry_type), optional, pointer  Reg,
real, intent(in), optional  dt,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout), optional  dzRegrid,
logical, intent(in), optional  initial 
)

For a state-based coordinate, accelerate the process of regridding by repeatedly applying the grid calculation algorithm.

Parameters
csALE control structure
[in,out]gOcean grid
[in]gvVertical grid
[in,out]hOriginal thicknesses
[in,out]tvThermo vars (T/S/EOS)
[in]nNumber of times to regrid
[in,out]uZonal velocity
[in,out]vMeridional velocity
regTracer registry to remap onto new grid
[in]dtModel timestep to provide a timescale for regridding
[in,out]dzregridFinal change in interface positions
[in]initialWhether we're being called from an initialization routine (and expect diagnostics to work)

Definition at line 638 of file MOM_ALE.F90.

638  type(ALE_CS), pointer :: CS !< ALE control structure
639  type(ocean_grid_type), intent(inout) :: G !< Ocean grid
640  type(verticalGrid_type), intent(in) :: GV !< Vertical grid
641  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
642  intent(inout) :: h !< Original thicknesses
643  type(thermo_var_ptrs), intent(inout) :: tv !< Thermo vars (T/S/EOS)
644  integer, intent(in) :: n !< Number of times to regrid
645  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
646  intent(inout) :: u !< Zonal velocity
647  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
648  intent(inout) :: v !< Meridional velocity
649  type(tracer_registry_type), &
650  optional, pointer :: Reg !< Tracer registry to remap onto new grid
651  real, optional, intent(in) :: dt !< Model timestep to provide a timescale for regridding
652  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), &
653  optional, intent(inout) :: dzRegrid !< Final change in interface positions
654  logical, optional, intent(in) :: initial !< Whether we're being called from an initialization
655  !! routine (and expect diagnostics to work)
656 
657  ! Local variables
658  integer :: i, j, k, nz
659  type(thermo_var_ptrs) :: tv_local ! local/intermediate temp/salt
660  type(group_pass_type) :: pass_T_S_h ! group pass if the coordinate has a stencil
661  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_loc, h_orig ! A working copy of layer thicknesses
662  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), target :: T, S ! local temporary state
663  ! we have to keep track of the total dzInterface if for some reason
664  ! we're using the old remapping algorithm for u/v
665  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzInterface, dzIntTotal
666 
667  nz = gv%ke
668 
669  ! initial total interface displacement due to successive regridding
670  dzinttotal(:,:,:) = 0.
671 
672  call create_group_pass(pass_t_s_h, t, g%domain)
673  call create_group_pass(pass_t_s_h, s, g%domain)
674  call create_group_pass(pass_t_s_h, h_loc, g%domain)
675 
676  ! copy original temp/salt and set our local tv_pointers to them
677  tv_local = tv
678  t(:,:,:) = tv%T(:,:,:)
679  s(:,:,:) = tv%S(:,:,:)
680  tv_local%T => t
681  tv_local%S => s
682 
683  ! get local copy of thickness and save original state for remapping
684  h_loc(:,:,:) = h(:,:,:)
685  h_orig(:,:,:) = h(:,:,:)
686 
687  ! Apply timescale to regridding (for e.g. filtered_grid_motion)
688  if (present(dt)) &
689  call ale_update_regrid_weights(dt, cs)
690 
691  do k = 1, n
692  call do_group_pass(pass_t_s_h, g%domain)
693 
694  ! generate new grid
695  call regridding_main(cs%remapCS, cs%regridCS, g, gv, h_loc, tv_local, h, dzinterface)
696  dzinttotal(:,:,:) = dzinttotal(:,:,:) + dzinterface(:,:,:)
697 
698  ! remap from original grid onto new grid
699  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
700  call remapping_core_h(cs%remapCS, nz, h_orig(i,j,:), tv%S(i,j,:), nz, h(i,j,:), tv_local%S(i,j,:))
701  call remapping_core_h(cs%remapCS, nz, h_orig(i,j,:), tv%T(i,j,:), nz, h(i,j,:), tv_local%T(i,j,:))
702  enddo ; enddo
703 
704  ! starting grid for next iteration
705  h_loc(:,:,:) = h(:,:,:)
706  enddo
707 
708  ! remap all state variables (including those that weren't needed for regridding)
709  call remap_all_state_vars(cs%remapCS, cs, g, gv, h_orig, h, reg, dzinttotal, u, v, dt=dt)
710 
711  ! save total dzregrid for diags if needed?
712  if (present(dzregrid)) dzregrid(:,:,:) = dzinttotal(:,:,:)

◆ ale_remap_init_conds()

logical function, public mom_ale::ale_remap_init_conds ( type(ale_cs), pointer  CS)

Returns true if initial conditions should be regridded and remapped.

Parameters
csmodule control structure

Definition at line 1156 of file MOM_ALE.F90.

1156  type(ALE_CS), pointer :: CS !< module control structure
1157 
1158  ale_remap_init_conds = .false.
1159  if (associated(cs)) ale_remap_init_conds = cs%remap_after_initialization

◆ ale_remap_scalar()

subroutine, public mom_ale::ale_remap_scalar ( type(remapping_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
integer, intent(in)  nk_src,
real, dimension(szi_(g),szj_(g),nk_src), intent(in)  h_src,
real, dimension(szi_(g),szj_(g),nk_src), intent(in)  s_src,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(in)  h_dst,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  s_dst,
logical, intent(in), optional  all_cells,
logical, intent(in), optional  old_remap 
)

Remaps a single scalar between grids described by thicknesses h_src and h_dst. h_dst must be dimensioned as a model array with GVke layers while h_src can have an arbitrary number of layers specified by nk_src.

Parameters
[in]csRemapping control structure
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in]nk_srcNumber of levels on source grid
[in]h_srcLevel thickness of source grid [H ~> m or kg-2]
[in]s_srcScalar on source grid
[in]h_dstLevel thickness of destination grid [H ~> m or kg-2]
[in,out]s_dstScalar on destination grid
[in]all_cellsIf false, only reconstruct for non-vanished cells. Use all vanished layers otherwise (default).
[in]old_remapIf true, use the old "remapping_core_w" method, otherwise use "remapping_core_h".

Definition at line 896 of file MOM_ALE.F90.

896  type(remapping_CS), intent(in) :: CS !< Remapping control structure
897  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
898  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
899  integer, intent(in) :: nk_src !< Number of levels on source grid
900  real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: h_src !< Level thickness of source grid
901  !! [H ~> m or kg-2]
902  real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: s_src !< Scalar on source grid
903  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(in) :: h_dst !< Level thickness of destination grid
904  !! [H ~> m or kg-2]
905  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: s_dst !< Scalar on destination grid
906  logical, optional, intent(in) :: all_cells !< If false, only reconstruct for
907  !! non-vanished cells. Use all vanished
908  !! layers otherwise (default).
909  logical, optional, intent(in) :: old_remap !< If true, use the old "remapping_core_w"
910  !! method, otherwise use "remapping_core_h".
911  ! Local variables
912  integer :: i, j, k, n_points
913  real :: dx(GV%ke+1)
914  real :: h_neglect, h_neglect_edge
915  logical :: ignore_vanished_layers, use_remapping_core_w
916 
917  ignore_vanished_layers = .false.
918  if (present(all_cells)) ignore_vanished_layers = .not. all_cells
919  use_remapping_core_w = .false.
920  if (present(old_remap)) use_remapping_core_w = old_remap
921  n_points = nk_src
922 
923  !### Try replacing both of these with GV%H_subroundoff
924  if (gv%Boussinesq) then
925  h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
926  else
927  h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
928  endif
929 
930  !$OMP parallel do default(shared) firstprivate(n_points,dx)
931  do j = g%jsc,g%jec ; do i = g%isc,g%iec
932  if (g%mask2dT(i,j) > 0.) then
933  if (ignore_vanished_layers) then
934  n_points = 0
935  do k = 1, nk_src
936  if (h_src(i,j,k)>0.) n_points = n_points + 1
937  enddo
938  s_dst(i,j,:) = 0.
939  endif
940  if (use_remapping_core_w) then
941  call dzfromh1h2( n_points, h_src(i,j,1:n_points), gv%ke, h_dst(i,j,:), dx )
942  call remapping_core_w(cs, n_points, h_src(i,j,1:n_points), s_src(i,j,1:n_points), &
943  gv%ke, dx, s_dst(i,j,:), h_neglect, h_neglect_edge)
944  else
945  call remapping_core_h(cs, n_points, h_src(i,j,1:n_points), s_src(i,j,1:n_points), &
946  gv%ke, h_dst(i,j,:), s_dst(i,j,:), h_neglect, h_neglect_edge)
947  endif
948  else
949  s_dst(i,j,:) = 0.
950  endif
951  enddo ; enddo
952 

◆ ale_update_regrid_weights()

subroutine, public mom_ale::ale_update_regrid_weights ( real, intent(in)  dt,
type(ale_cs), pointer  CS 
)

Updates the weights for time filtering the new grid generated in regridding.

Parameters
[in]dtTime-step used between ALE calls
csALE control structure

Definition at line 1164 of file MOM_ALE.F90.

1164  real, intent(in) :: dt !< Time-step used between ALE calls
1165  type(ALE_CS), pointer :: CS !< ALE control structure
1166  ! Local variables
1167  real :: w ! An implicit weighting estimate.
1168 
1169  if (associated(cs)) then
1170  w = 0.0
1171  if (cs%regrid_time_scale > 0.0) then
1172  w = cs%regrid_time_scale / (cs%regrid_time_scale + dt)
1173  endif
1174  call set_regrid_params(cs%regridCS, old_grid_weight=w)
1175  endif
1176 

◆ ale_updateverticalgridtype()

subroutine, public mom_ale::ale_updateverticalgridtype ( type(ale_cs), pointer  CS,
type(verticalgrid_type), pointer  GV 
)

Update the vertical grid type with ALE information. This subroutine sets information in the verticalGrid_type to be consistent with the use of ALE mode.

Parameters
csALE control structure
gvvertical grid information

Definition at line 1183 of file MOM_ALE.F90.

1183  type(ALE_CS), pointer :: CS !< ALE control structure
1184  type(verticalGrid_type), pointer :: GV !< vertical grid information
1185 
1186  integer :: nk
1187 
1188  nk = gv%ke
1189  gv%sInterface(1:nk+1) = getcoordinateinterfaces( cs%regridCS, undo_scaling=.true. )
1190  gv%sLayer(1:nk) = 0.5*( gv%sInterface(1:nk) + gv%sInterface(2:nk+1) )
1191  gv%zAxisUnits = getcoordinateunits( cs%regridCS )
1192  gv%zAxisLongName = getcoordinateshortname( cs%regridCS )
1193  gv%direction = -1 ! Because of ferret in z* mode. Need method to set
1194  ! as function of coordinae mode.
1195 

◆ ale_writecoordinatefile()

subroutine, public mom_ale::ale_writecoordinatefile ( type(ale_cs), pointer  CS,
type(verticalgrid_type), intent(in)  GV,
character(len=*), intent(in)  directory 
)

Write the vertical coordinate information into a file. This subroutine writes out a file containing any available data related to the vertical grid used by the MOM ocean model when in ALE mode.

Parameters
csmodule control structure
[in]gvocean vertical grid structure
[in]directorydirectory for writing grid info

Definition at line 1203 of file MOM_ALE.F90.

1203  type(ALE_CS), pointer :: CS !< module control structure
1204  type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure
1205  character(len=*), intent(in) :: directory !< directory for writing grid info
1206 
1207  character(len=240) :: filepath
1208  type(vardesc) :: vars(2)
1209  type(fieldtype) :: fields(2)
1210  integer :: unit
1211  real :: ds(GV%ke), dsi(GV%ke+1)
1212 
1213  filepath = trim(directory) // trim("Vertical_coordinate")
1214  ds(:) = getcoordinateresolution( cs%regridCS, undo_scaling=.true. )
1215  dsi(1) = 0.5*ds(1)
1216  dsi(2:gv%ke) = 0.5*( ds(1:gv%ke-1) + ds(2:gv%ke) )
1217  dsi(gv%ke+1) = 0.5*ds(gv%ke)
1218 
1219  vars(1) = var_desc('ds', getcoordinateunits( cs%regridCS ), &
1220  'Layer Coordinate Thickness','1','L','1')
1221  vars(2) = var_desc('ds_interface', getcoordinateunits( cs%regridCS ), &
1222  'Layer Center Coordinate Separation','1','i','1')
1223 
1224  call create_file(unit, trim(filepath), vars, 2, fields, single_file, gv=gv)
1225  call write_field(unit, fields(1), ds)
1226  call write_field(unit, fields(2), dsi)
1227  call close_file(unit)
1228 

◆ check_grid()

subroutine mom_ale::check_grid ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
real, intent(in)  threshold 
)
private

Check grid for negative thicknesses.

Parameters
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in]hCurrent 3D grid obtained after the last time step [H ~> m or kg m-2]
[in]thresholdValue below which to flag issues, [H ~> m or kg m-2]

Definition at line 567 of file MOM_ALE.F90.

567  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
568  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
569  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Current 3D grid obtained after the
570  !! last time step [H ~> m or kg m-2]
571  real, intent(in) :: threshold !< Value below which to flag issues,
572  !! [H ~> m or kg m-2]
573  ! Local variables
574  integer :: i, j
575 
576  do j = g%jsc,g%jec ; do i = g%isc,g%iec
577  if (g%mask2dT(i,j)>0.) then
578  if (minval(h(i,j,:)) < threshold) then
579  write(0,*) 'check_grid: i,j=',i,j,'h(i,j,:)=',h(i,j,:)
580  if (threshold <= 0.) then
581  call mom_error(fatal,"MOM_ALE, check_grid: negative thickness encountered.")
582  else
583  call mom_error(fatal,"MOM_ALE, check_grid: too tiny thickness encountered.")
584  endif
585  endif
586  endif
587  enddo ; enddo
588 
589 

◆ pressure_gradient_plm()

subroutine, public mom_ale::pressure_gradient_plm ( type(ale_cs), intent(inout)  CS,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  S_t,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  S_b,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  T_t,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  T_b,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(in)  h,
logical, intent(in)  bdry_extrap 
)

Use plm reconstruction for pressure gradient (determine edge values) By using a PLM (limited piecewise linear method) reconstruction, this routine determines the edge values for the salinity and temperature within each layer. These edge values are returned and are used to compute the pressure gradient (by computing the densities).

Parameters
[in]gocean grid structure
[in]gvOcean vertical grid structure
[in,out]csmodule control structure
[in,out]s_tSalinity at the top edge of each layer
[in,out]s_bSalinity at the bottom edge of each layer
[in,out]t_tTemperature at the top edge of each layer
[in,out]t_bTemperature at the bottom edge of each layer
[in]tvthermodynamics structure
[in]hlayer thickness [H ~> m or kg m-2]
[in]bdry_extrapIf true, use high-order boundary extrapolation within boundary cells

Definition at line 962 of file MOM_ALE.F90.

962  type(ocean_grid_type), intent(in) :: G !< ocean grid structure
963  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
964  type(ALE_CS), intent(inout) :: CS !< module control structure
965  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
966  intent(inout) :: S_t !< Salinity at the top edge of each layer
967  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
968  intent(inout) :: S_b !< Salinity at the bottom edge of each layer
969  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
970  intent(inout) :: T_t !< Temperature at the top edge of each layer
971  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
972  intent(inout) :: T_b !< Temperature at the bottom edge of each layer
973  type(thermo_var_ptrs), intent(in) :: tv !< thermodynamics structure
974  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
975  intent(in) :: h !< layer thickness [H ~> m or kg m-2]
976  logical, intent(in) :: bdry_extrap !< If true, use high-order boundary
977  !! extrapolation within boundary cells
978 
979  ! Local variables
980  integer :: i, j, k
981  real :: hTmp(GV%ke)
982  real :: tmp(GV%ke)
983  real, dimension(CS%nk,2) :: ppol_E !Edge value of polynomial
984  real, dimension(CS%nk,2) :: ppol_coefs !Coefficients of polynomial
985  real :: h_neglect
986 
987  !### Replace this with GV%H_subroundoff
988  if (gv%Boussinesq) then
989  h_neglect = gv%m_to_H*1.0e-30
990  else
991  h_neglect = gv%kg_m2_to_H*1.0e-30
992  endif
993 
994  ! Determine reconstruction within each column
995  !$OMP parallel do default(shared) private(hTmp,ppol_E,ppol_coefs,tmp)
996  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
997  ! Build current grid
998  htmp(:) = h(i,j,:)
999  tmp(:) = tv%S(i,j,:)
1000  ! Reconstruct salinity profile
1001  ppol_e(:,:) = 0.0
1002  ppol_coefs(:,:) = 0.0
1003  call plm_reconstruction( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1004  if (bdry_extrap) &
1005  call plm_boundary_extrapolation( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1006 
1007  do k = 1,gv%ke
1008  s_t(i,j,k) = ppol_e(k,1)
1009  s_b(i,j,k) = ppol_e(k,2)
1010  enddo
1011 
1012  ! Reconstruct temperature profile
1013  ppol_e(:,:) = 0.0
1014  ppol_coefs(:,:) = 0.0
1015  tmp(:) = tv%T(i,j,:)
1016  call plm_reconstruction( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1017  if (bdry_extrap) &
1018  call plm_boundary_extrapolation( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1019 
1020  do k = 1,gv%ke
1021  t_t(i,j,k) = ppol_e(k,1)
1022  t_b(i,j,k) = ppol_e(k,2)
1023  enddo
1024 
1025  enddo ; enddo
1026 

◆ pressure_gradient_ppm()

subroutine, public mom_ale::pressure_gradient_ppm ( type(ale_cs), intent(inout)  CS,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  S_t,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  S_b,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  T_t,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  T_b,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(in)  h,
logical, intent(in)  bdry_extrap 
)

Use ppm reconstruction for pressure gradient (determine edge values) By using a PPM (limited piecewise linear method) reconstruction, this routine determines the edge values for the salinity and temperature within each layer. These edge values are returned and are used to compute the pressure gradient (by computing the densities).

Parameters
[in]gocean grid structure
[in]gvOcean vertical grid structure
[in,out]csmodule control structure
[in,out]s_tSalinity at the top edge of each layer
[in,out]s_bSalinity at the bottom edge of each layer
[in,out]t_tTemperature at the top edge of each layer
[in,out]t_bTemperature at the bottom edge of each layer
[in]tvthermodynamics structure
[in]hlayer thicknesses [H ~> m or kg m-2]
[in]bdry_extrapIf true, use high-order boundary extrapolation within boundary cells

Definition at line 1036 of file MOM_ALE.F90.

1036  type(ocean_grid_type), intent(in) :: G !< ocean grid structure
1037  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
1038  type(ALE_CS), intent(inout) :: CS !< module control structure
1039  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1040  intent(inout) :: S_t !< Salinity at the top edge of each layer
1041  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1042  intent(inout) :: S_b !< Salinity at the bottom edge of each layer
1043  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1044  intent(inout) :: T_t !< Temperature at the top edge of each layer
1045  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1046  intent(inout) :: T_b !< Temperature at the bottom edge of each layer
1047  type(thermo_var_ptrs), intent(in) :: tv !< thermodynamics structure
1048  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1049  intent(in) :: h !< layer thicknesses [H ~> m or kg m-2]
1050  logical, intent(in) :: bdry_extrap !< If true, use high-order boundary
1051  !! extrapolation within boundary cells
1052 
1053  ! Local variables
1054  integer :: i, j, k
1055  real :: hTmp(GV%ke)
1056  real :: tmp(GV%ke)
1057  real, dimension(CS%nk,2) :: &
1058  ppol_E !Edge value of polynomial
1059  real, dimension(CS%nk,3) :: &
1060  ppol_coefs !Coefficients of polynomial
1061  real :: h_neglect, h_neglect_edge
1062 
1063  !### Try replacing both of these with GV%H_subroundoff
1064  if (gv%Boussinesq) then
1065  h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
1066  else
1067  h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
1068  endif
1069 
1070  ! Determine reconstruction within each column
1071  !$OMP parallel do default(shared) private(hTmp,tmp,ppol_E,ppol_coefs)
1072  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
1073 
1074  ! Build current grid
1075  htmp(:) = h(i,j,:)
1076  tmp(:) = tv%S(i,j,:)
1077 
1078  ! Reconstruct salinity profile
1079  ppol_e(:,:) = 0.0
1080  ppol_coefs(:,:) = 0.0
1081  !### Try to replace the following value of h_neglect with GV%H_subroundoff.
1082  call edge_values_implicit_h4( gv%ke, htmp, tmp, ppol_e, h_neglect=h_neglect_edge )
1083  call ppm_reconstruction( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1084  if (bdry_extrap) &
1085  call ppm_boundary_extrapolation( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1086 
1087  do k = 1,gv%ke
1088  s_t(i,j,k) = ppol_e(k,1)
1089  s_b(i,j,k) = ppol_e(k,2)
1090  enddo
1091 
1092  ! Reconstruct temperature profile
1093  ppol_e(:,:) = 0.0
1094  ppol_coefs(:,:) = 0.0
1095  tmp(:) = tv%T(i,j,:)
1096  !### Try to replace the following value of h_neglect with GV%H_subroundoff.
1097  call edge_values_implicit_h4( gv%ke, htmp, tmp, ppol_e, h_neglect=1.0e-10*gv%m_to_H )
1098  call ppm_reconstruction( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1099  if (bdry_extrap) &
1100  call ppm_boundary_extrapolation(gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1101 
1102  do k = 1,gv%ke
1103  t_t(i,j,k) = ppol_e(k,1)
1104  t_b(i,j,k) = ppol_e(k,2)
1105  enddo
1106 
1107  enddo ; enddo
1108 

◆ remap_all_state_vars()

subroutine mom_ale::remap_all_state_vars ( type(remapping_cs), intent(in)  CS_remapping,
type(ale_cs), intent(in)  CS_ALE,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(in)  h_old,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(in)  h_new,
type(tracer_registry_type), pointer  Reg,
real, dimension(szi_(g),szj_(g),szk_(gv)+1), intent(in), optional  dxInterface,
real, dimension(szib_(g),szj_(g),szk_(gv)), intent(inout), optional  u,
real, dimension(szi_(g),szjb_(g),szk_(gv)), intent(inout), optional  v,
logical, intent(in), optional  debug,
real, intent(in), optional  dt 
)
private

This routine takes care of remapping all variable between the old and the new grids. When velocity components need to be remapped, thicknesses at velocity points are taken to be arithmetic averages of tracer thicknesses. This routine is called during initialization of the model at time=0, to remap initiali conditions to the model grid. It is also called during a time step to update the state.

Parameters
[in]cs_remappingRemapping control structure
[in]cs_aleALE control structure
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in]h_oldThickness of source grid [H ~> m or kg-2]
[in]h_newThickness of destination grid [H ~> m or kg-2]
regTracer registry structure
[in]dxinterfaceChange in interface position
[in,out]uZonal velocity component [m s-1]
[in,out]vMeridional velocity component [m s-1]
[in]debugIf true, show the call tree
[in]dttime step for diagnostics

Definition at line 722 of file MOM_ALE.F90.

722  type(remapping_CS), intent(in) :: CS_remapping !< Remapping control structure
723  type(ALE_CS), intent(in) :: CS_ALE !< ALE control structure
724  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
725  type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure
726  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_old !< Thickness of source grid
727  !! [H ~> m or kg-2]
728  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_new !< Thickness of destination grid
729  !! [H ~> m or kg-2]
730  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
731  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), &
732  optional, intent(in) :: dxInterface !< Change in interface position
733  !! [H ~> m or kg-2]
734  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
735  optional, intent(inout) :: u !< Zonal velocity component [m s-1]
736  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
737  optional, intent(inout) :: v !< Meridional velocity component [m s-1]
738  logical, optional, intent(in) :: debug !< If true, show the call tree
739  real, optional, intent(in) :: dt !< time step for diagnostics
740  ! Local variables
741  integer :: i, j, k, m
742  integer :: nz, ntr
743  real, dimension(GV%ke+1) :: dx
744  real, dimension(GV%ke) :: h1, u_column
745  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: work_conc
746  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: work_cont
747  real, dimension(SZI_(G), SZJ_(G)) :: work_2d
748  real :: Idt, ppt2mks
749  real, dimension(GV%ke) :: h2
750  real :: h_neglect, h_neglect_edge
751  logical :: show_call_tree
752  type(tracer_type), pointer :: Tr => null()
753 
754  show_call_tree = .false.
755  if (present(debug)) show_call_tree = debug
756  if (show_call_tree) call calltree_enter("remap_all_state_vars(), MOM_ALE.F90")
757 
758  ! If remap_uv_using_old_alg is .true. and u or v is requested, then we must have dxInterface. Otherwise,
759  ! u and v can be remapped without dxInterface
760  if ( .not. present(dxinterface) .and. (cs_ale%remap_uv_using_old_alg .and. (present(u) .or. present(v))) ) then
761  call mom_error(fatal, "remap_all_state_vars: dxInterface must be present if using old algorithm "// &
762  "and u/v are to be remapped")
763  endif
764 
765  !### Try replacing both of these with GV%H_subroundoff
766  if (gv%Boussinesq) then
767  h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
768  else
769  h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
770  endif
771 
772  nz = gv%ke
773  ppt2mks = 0.001
774 
775  ntr = 0 ; if (associated(reg)) ntr = reg%ntr
776 
777  if (present(dt)) then
778  idt = 1.0/dt
779  work_conc(:,:,:) = 0.0
780  work_cont(:,:,:) = 0.0
781  endif
782 
783  ! Remap tracer
784  if (ntr>0) then
785  if (show_call_tree) call calltree_waypoint("remapping tracers (remap_all_state_vars)")
786  !$OMP parallel do default(shared) private(h1,h2,u_column,Tr)
787  do m=1,ntr ! For each tracer
788  tr => reg%Tr(m)
789  do j = g%jsc,g%jec ; do i = g%isc,g%iec ; if (g%mask2dT(i,j)>0.) then
790  ! Build the start and final grids
791  h1(:) = h_old(i,j,:)
792  h2(:) = h_new(i,j,:)
793  call remapping_core_h(cs_remapping, nz, h1, tr%t(i,j,:), nz, h2, &
794  u_column, h_neglect, h_neglect_edge)
795 
796  ! Intermediate steps for tendency of tracer concentration and tracer content.
797  if (present(dt)) then
798  if (tr%id_remap_conc>0) then
799  do k=1,gv%ke
800  work_conc(i,j,k) = (u_column(k) - tr%t(i,j,k) ) * idt
801  enddo
802  endif
803  if (tr%id_remap_cont>0. .or. tr%id_remap_cont_2d>0) then
804  do k=1,gv%ke
805  work_cont(i,j,k) = (u_column(k)*h2(k) - tr%t(i,j,k)*h1(k)) * idt
806  enddo
807  endif
808  endif
809  ! update tracer concentration
810  tr%t(i,j,:) = u_column(:)
811  endif ; enddo ; enddo
812 
813  ! tendency diagnostics.
814  if (present(dt)) then
815  if (tr%id_remap_conc > 0) then
816  call post_data(tr%id_remap_conc, work_conc, cs_ale%diag)
817  endif
818  if (tr%id_remap_cont > 0) then
819  call post_data(tr%id_remap_cont, work_cont, cs_ale%diag)
820  endif
821  if (tr%id_remap_cont_2d > 0) then
822  do j = g%jsc,g%jec ; do i = g%isc,g%iec
823  work_2d(i,j) = 0.0
824  do k = 1,gv%ke
825  work_2d(i,j) = work_2d(i,j) + work_cont(i,j,k)
826  enddo
827  enddo ; enddo
828  call post_data(tr%id_remap_cont_2d, work_2d, cs_ale%diag)
829  endif
830  endif
831  enddo ! m=1,ntr
832 
833  endif ! endif for ntr > 0
834 
835  if (show_call_tree) call calltree_waypoint("tracers remapped (remap_all_state_vars)")
836 
837  ! Remap u velocity component
838  if ( present(u) ) then
839  !$OMP parallel do default(shared) private(h1,h2,dx,u_column)
840  do j = g%jsc,g%jec ; do i = g%iscB,g%iecB ; if (g%mask2dCu(i,j)>0.) then
841  ! Build the start and final grids
842  h1(:) = 0.5 * ( h_old(i,j,:) + h_old(i+1,j,:) )
843  if (cs_ale%remap_uv_using_old_alg) then
844  dx(:) = 0.5 * ( dxinterface(i,j,:) + dxinterface(i+1,j,:) )
845  do k = 1, nz
846  h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
847  enddo
848  else
849  h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i+1,j,:) )
850  endif
851  call remapping_core_h(cs_remapping, nz, h1, u(i,j,:), nz, h2, &
852  u_column, h_neglect, h_neglect_edge)
853  u(i,j,:) = u_column(:)
854  endif ; enddo ; enddo
855  endif
856 
857  if (show_call_tree) call calltree_waypoint("u remapped (remap_all_state_vars)")
858 
859  ! Remap v velocity component
860  if ( present(v) ) then
861  !$OMP parallel do default(shared) private(h1,h2,dx,u_column)
862  do j = g%jscB,g%jecB ; do i = g%isc,g%iec ; if (g%mask2dCv(i,j)>0.) then
863  ! Build the start and final grids
864  h1(:) = 0.5 * ( h_old(i,j,:) + h_old(i,j+1,:) )
865  if (cs_ale%remap_uv_using_old_alg) then
866  dx(:) = 0.5 * ( dxinterface(i,j,:) + dxinterface(i,j+1,:) )
867  do k = 1, nz
868  h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
869  enddo
870  else
871  h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i,j+1,:) )
872  endif
873  call remapping_core_h(cs_remapping, nz, h1, v(i,j,:), nz, h2, &
874  u_column, h_neglect, h_neglect_edge)
875  v(i,j,:) = u_column(:)
876  endif ; enddo ; enddo
877  endif
878 
879  if (cs_ale%id_vert_remap_h > 0) call post_data(cs_ale%id_vert_remap_h, h_old, cs_ale%diag)
880  if ((cs_ale%id_vert_remap_h_tendency > 0) .and. present(dt)) then
881  do k = 1, nz ; do j = g%jsc,g%jec ; do i = g%isc,g%iec
882  work_cont(i,j,k) = (h_new(i,j,k) - h_old(i,j,k))*idt
883  enddo ; enddo ; enddo
884  call post_data(cs_ale%id_vert_remap_h_tendency, work_cont, cs_ale%diag)
885  endif
886  if (show_call_tree) call calltree_waypoint("v remapped (remap_all_state_vars)")
887  if (show_call_tree) call calltree_leave("remap_all_state_vars()")
888