MOM6
MOM_ALE.F90
Go to the documentation of this file.
1 !> This module contains the main regridding routines.
2 !! Regridding comprises two steps:
3 !! (1) Interpolation and creation of a new grid based on target interface
4 !! densities (or any other criterion).
5 !! (2) Remapping of quantities between old grid and new grid.
6 !! Original module written by Laurent White, 2008.06.09
7 module mom_ale
8 
9 ! This file is part of MOM6. See LICENSE.md for the license.
10 
14 use mom_domains, only : create_group_pass, do_group_pass, group_pass_type
15 use mom_eos, only : calculate_density
16 use mom_domains, only : create_group_pass, do_group_pass, group_pass_type
17 use mom_error_handler, only : mom_error, fatal, warning
21 use mom_io, only : vardesc, var_desc, fieldtype, single_file
22 use mom_io, only : create_file, write_field, close_file
27 use mom_regridding, only : regriddingcoordinatemodedoc, default_coordinate_mode
43 use mom_variables, only : ocean_grid_type, thermo_var_ptrs
45 
47 !use regrid_consts, only : coordinateMode, DEFAULT_COORDINATE_MODE
54 
55 
56 implicit none ; private
57 #include <MOM_memory.h>
58 
59 
60 !> ALE control structure
61 type, public :: ale_cs
62  private
63 
64  logical :: boundary_extrapolation_for_pressure !< Indicate whether high-order boundary
65  !! extrapolation should be used within boundary cells
66 
67  logical :: reconstructforpressure = .false. !< Indicates whether integrals for FV
68  !! pressure gradient calculation will
69  !! use reconstruction of T/S.
70  !! By default, it is true if regridding
71  !! has been initialized, otherwise false.
72 
73  integer :: pressurereconstructionscheme !< Form of the reconstruction of T/S
74  !! for FV pressure gradient calculation.
75  !! By default, it is =1 (PLM)
76 
77  logical :: remap_uv_using_old_alg !< If true, uses the old "remapping via a delta z"
78  !! method. If False, uses the new method that
79  !! remaps between grids described by h.
80 
81  real :: regrid_time_scale !< The time-scale used in blending between the current (old) grid
82  !! and the target (new) grid. (s)
83 
84  type(regridding_cs) :: regridcs !< Regridding parameters and work arrays
85  type(remapping_cs) :: remapcs !< Remapping parameters and work arrays
86 
87  integer :: nk !< Used only for queries, not directly by this module
88  integer :: degree_linear=1 !< Degree of linear piecewise polynomial
89  integer :: degree_parab=2 !< Degree of parabolic piecewise polynomial
90 
91  logical :: remap_after_initialization !< Indicates whether to regrid/remap after initializing the state.
92 
93  logical :: show_call_tree !< For debugging
94  real :: c_p !< seawater heat capacity (J/(kg deg C))
95 
96  ! for diagnostics
97  type(diag_ctrl), pointer :: diag !< structure to regulate output
98  integer, dimension(:), allocatable :: id_tracer_remap_tendency !< diagnostic id
99  integer, dimension(:), allocatable :: id_htracer_remap_tendency !< diagnostic id
100  integer, dimension(:), allocatable :: id_htracer_remap_tendency_2d !< diagnostic id
101  logical, dimension(:), allocatable :: do_tendency_diag !< flag for doing diagnostics
102  integer :: id_dzregrid = -1 !< diagnostic id
103 
104 end type
105 
106 ! Publicly available functions
107 public ale_init
108 public ale_end
109 public ale_main
110 public ale_main_offline
111 public ale_offline_inputs
113 public ale_build_grid
115 public ale_remap_scalar
121 public ale_initregridding
122 public ale_getcoordinate
129 public ale_register_diags
130 
131 contains
132 
133 !> This routine is typically called (from initialize_MOM in file MOM.F90)
134 !! before the main time integration loop to initialize the regridding stuff.
135 !! We read the MOM_input file to register the values of different
136 !! regridding/remapping parameters.
137 subroutine ale_init( param_file, GV, max_depth, CS)
138  type(param_file_type), intent(in) :: param_file !< Parameter file
139  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
140  real, intent(in) :: max_depth !< The maximum depth of the ocean, in m.
141  type(ale_cs), pointer :: CS !< Module control structure
142 
143  ! Local variables
144  real, dimension(:), allocatable :: dz
145  character(len=40) :: mdl = "MOM_ALE" ! This module's name.
146  character(len=80) :: string ! Temporary strings
147  real :: filter_shallow_depth, filter_deep_depth
148  logical :: check_reconstruction
149  logical :: check_remapping
150  logical :: force_bounds_in_subcell
151  logical :: local_logical
152 
153  if (associated(cs)) then
154  call mom_error(warning, "ALE_init called with an associated "// &
155  "control structure.")
156  return
157  endif
158  allocate(cs)
159 
160  cs%show_call_tree = calltree_showquery()
161  if (cs%show_call_tree) call calltree_enter("ALE_init(), MOM_ALE.F90")
162 
163  ! --- BOUNDARY EXTRAPOLATION --
164  ! This sets whether high-order (rather than PCM) reconstruction schemes
165  ! should be used within boundary cells
166  call get_param(param_file, mdl, "BOUNDARY_EXTRAPOLATION_PRESSURE", &
167  cs%boundary_extrapolation_for_pressure, &
168  "When defined, the reconstruction is extrapolated\n"//&
169  "within boundary cells rather than assume PCM for the.\n"//&
170  "calculation of pressure. e.g. if PPM is used, a\n"//&
171  "PPM reconstruction will also be used within\n"//&
172  "boundary cells.", default=.true.)
173 
174  ! --- PRESSURE GRADIENT CALCULATION ---
175  call get_param(param_file, mdl, "RECONSTRUCT_FOR_PRESSURE", &
176  cs%reconstructForPressure , &
177  "If True, use vertical reconstruction of T/S within\n"//&
178  "the integrals of teh FV pressure gradient calculation.\n"//&
179  "If False, use the constant-by-layer algorithm.\n"//&
180  "By default, this is True when using ALE and False otherwise.", &
181  default=.true. )
182 
183  call get_param(param_file, mdl, "PRESSURE_RECONSTRUCTION_SCHEME", &
184  cs%pressureReconstructionScheme, &
185  "Type of vertical reconstruction of T/S to use in integrals\n"//&
186  "within the FV pressure gradient calculation."//&
187  " 1: PLM reconstruction.\n"//&
188  " 2: PPM reconstruction.", default=pressure_reconstruction_plm)
189 
190  call get_param(param_file, mdl, "REMAP_UV_USING_OLD_ALG", &
191  cs%remap_uv_using_old_alg, &
192  "If true, uses the old remapping-via-a-delta-z method for\n"//&
193  "remapping u and v. If false, uses the new method that remaps\n"//&
194  "between grids described by an old and new thickness.", &
195  default=.true.)
196 
197  ! Initialize and configure regridding
198  call ale_initregridding( gv, max_depth, param_file, mdl, cs%regridCS)
199 
200  ! Initialize and configure remapping
201  call get_param(param_file, mdl, "REMAPPING_SCHEME", string, &
202  "This sets the reconstruction scheme used\n"//&
203  "for vertical remapping for all variables.\n"//&
204  "It can be one of the following schemes:\n"//&
205  trim(remappingschemesdoc), default=remappingdefaultscheme)
206  call get_param(param_file, mdl, "FATAL_CHECK_RECONSTRUCTIONS", check_reconstruction, &
207  "If true, cell-by-cell reconstructions are checked for\n"//&
208  "consistency and if non-monotonicty or an inconsistency is\n"//&
209  "detected then a FATAL error is issued.", default=.false.)
210  call get_param(param_file, mdl, "FATAL_CHECK_REMAPPING", check_remapping, &
211  "If true, the results of remapping are checked for\n"//&
212  "conservation and new extrema and if an inconsistency is\n"//&
213  "detected then a FATAL error is issued.", default=.false.)
214  call get_param(param_file, mdl, "REMAP_BOUND_INTERMEDIATE_VALUES", force_bounds_in_subcell, &
215  "If true, the values on the intermediate grid used for remapping\n"//&
216  "are forced to be bounded, which might not be the case due to\n"//&
217  "round off.", default=.false.)
218  call initialize_remapping( cs%remapCS, string, &
219  boundary_extrapolation=.false., &
220  check_reconstruction=check_reconstruction, &
221  check_remapping=check_remapping, &
222  force_bounds_in_subcell=force_bounds_in_subcell)
223 
224  call get_param(param_file, mdl, "REMAP_AFTER_INITIALIZATION", cs%remap_after_initialization, &
225  "If true, applies regridding and remapping immediately after\n"//&
226  "initialization so that the state is ALE consistent. This is a\n"//&
227  "legacy step and should not be needed if the initialization is\n"//&
228  "consistent with the coordinate mode.", default=.true.)
229 
230  call get_param(param_file, mdl, "REGRID_TIME_SCALE", cs%regrid_time_scale, &
231  "The time-scale used in blending between the current (old) grid\n"//&
232  "and the target (new) grid. A short time-scale favors the target\n"//&
233  "grid (0. or anything less than DT_THERM) has no memory of the old\n"//&
234  "grid. A very long time-scale makes the model more Lagrangian.", &
235  units="s", default=0.)
236  call get_param(param_file, mdl, "REGRID_FILTER_SHALLOW_DEPTH", filter_shallow_depth, &
237  "The depth above which no time-filtering is applied. Above this depth\n"//&
238  "final grid exactly matches the target (new) grid.", units="m", default=0.)
239  call get_param(param_file, mdl, "REGRID_FILTER_DEEP_DEPTH", filter_deep_depth, &
240  "The depth below which full time-filtering is applied with time-scale\n"//&
241  "REGRID_TIME_SCALE. Between depths REGRID_FILTER_SHALLOW_DEPTH and\n"//&
242  "REGRID_FILTER_SHALLOW_DEPTH the filter wieghts adopt a cubic profile.", &
243  units="m", default=0.)
244  call set_regrid_params(cs%regridCS, depth_of_time_filter_shallow=filter_shallow_depth*gv%m_to_H, &
245  depth_of_time_filter_deep=filter_deep_depth*gv%m_to_H)
246  call get_param(param_file, mdl, "REGRID_USE_OLD_DIRECTION", local_logical, &
247  "If true, the regridding ntegrates upwards from the bottom for\n"//&
248  "interface positions, much as the main model does. If false\n"//&
249  "regridding integrates downward, consistant with the remapping\n"//&
250  "code.", default=.true., do_not_log=.true.)
251  call set_regrid_params(cs%regridCS, integrate_downward_for_e=.not.local_logical)
252 
253  ! Keep a record of values for subsequent queries
254  cs%nk = gv%ke
255 
256  if (cs%show_call_tree) call calltree_leave("ALE_init()")
257 end subroutine ale_init
258 
259 !> Initialize diagnostics for the ALE module.
260 subroutine ale_register_diags(Time, G, diag, C_p, Reg, CS)
261  type(time_type),target, intent(in) :: Time !< Time structure
262  type(ocean_grid_type), intent(in) :: G !< Grid structure
263  type(diag_ctrl), target, intent(in) :: diag !< Diagnostics control structure
264  real, intent(in) :: C_p !< seawater heat capacity (J/(kg deg C))
265  type(tracer_registry_type), pointer :: Reg !< Tracer registry
266  type(ale_cs), pointer :: CS !< Module control structure
267 
268  integer :: m, ntr, nsize
269 
270  if (associated(reg)) then
271  ntr = reg%ntr
272  else
273  ntr = 0
274  endif
275  nsize = max(1,ntr)
276 
277  cs%diag => diag
278  cs%C_p = c_p
279 
280  allocate(cs%id_tracer_remap_tendency(nsize))
281  allocate(cs%id_Htracer_remap_tendency(nsize))
282  allocate(cs%id_Htracer_remap_tendency_2d(nsize))
283  allocate(cs%do_tendency_diag(nsize))
284  cs%do_tendency_diag(:) = .false.
285  cs%id_tracer_remap_tendency(:) = -1
286  cs%id_Htracer_remap_tendency(:) = -1
287  cs%id_Htracer_remap_tendency_2d(:) = -1
288 
289  cs%id_dzRegrid = register_diag_field('ocean_model','dzRegrid',diag%axesTi,time, &
290  'Change in interface height due to ALE regridding', 'meter')
291 
292  if(ntr > 0) then
293 
294  do m=1,ntr
295  if(trim(reg%Tr(m)%name) == 'T') then
296 
297  cs%id_tracer_remap_tendency(m) = register_diag_field('ocean_model', &
298  trim(reg%Tr(m)%name)//'_tendency_vert_remap', diag%axesTL, time, &
299  'Tendency from vertical remapping for tracer concentration '//trim(reg%Tr(m)%name),&
300  'degC/s')
301 
302  cs%id_Htracer_remap_tendency(m) = register_diag_field('ocean_model',&
303  trim(reg%Tr(m)%name)//'h_tendency_vert_remap', diag%axesTL, time, &
304  'Tendency from vertical remapping for heat', &
305  'W/m2',v_extensive=.true.)
306 
307  cs%id_Htracer_remap_tendency_2d(m) = register_diag_field('ocean_model',&
308  trim(reg%Tr(m)%name)//'h_tendency_vert_remap_2d', diag%axesT1, time, &
309  'Vertical sum of tendency from vertical remapping for heat', &
310  'W/m2')
311 
312  else
313 
314  cs%id_tracer_remap_tendency(m) = register_diag_field('ocean_model', &
315  trim(reg%Tr(m)%name)//'_tendency_vert_remap', diag%axesTL, time, &
316  'Tendency from vertical remapping for tracer concentration '//trim(reg%Tr(m)%name),&
317  'tracer conc / sec')
318 
319  cs%id_Htracer_remap_tendency(m) = register_diag_field('ocean_model', &
320  trim(reg%Tr(m)%name)//'h_tendency_vert_remap', diag%axesTL, time, &
321  'Tendency from vertical remapping for tracer content '//trim(reg%Tr(m)%name),&
322  'kg m-2 s-1',v_extensive=.true.)
323 
324  cs%id_Htracer_remap_tendency_2d(m) = register_diag_field('ocean_model', &
325  trim(reg%Tr(m)%name)//'h_tendency_vert_remap_2d', diag%axesT1, time, &
326  'Vertical sum of tendency from vertical remapping for tracer content '//trim(reg%Tr(m)%name),&
327  'kg m-2 s-1')
328 
329  endif
330 
331  if(cs%id_tracer_remap_tendency(m) > 0) cs%do_tendency_diag(m) = .true.
332  if(cs%id_Htracer_remap_tendency(m) > 0) cs%do_tendency_diag(m) = .true.
333  if(cs%id_Htracer_remap_tendency_2d(m) > 0) cs%do_tendency_diag(m) = .true.
334 
335  enddo ! m loop over tracers
336 
337  endif ! ntr > 0
338 
339 end subroutine ale_register_diags
340 
341 !> Crudely adjust (initial) grid for integrity.
342 !! This routine is typically called (from initialize_MOM in file MOM.F90)
343 !! before the main time integration loop to initialize the regridding stuff.
344 !! We read the MOM_input file to register the values of different
345 !! regridding/remapping parameters.
346 subroutine adjustgridforintegrity( CS, G, GV, h )
347  type(ale_cs), pointer :: CS !< Regridding parameters and options
348  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
349  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
350  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid thickness that
351  !! are to be adjusted (m or Pa)
352  call inflate_vanished_layers_old( cs%regridCS, g, gv, h(:,:,:) )
353 
354 end subroutine adjustgridforintegrity
355 
356 
357 !> End of regridding (memory deallocation).
358 !! This routine is typically called (from MOM_end in file MOM.F90)
359 !! after the main time integration loop to deallocate the regridding stuff.
360 subroutine ale_end(CS)
361  type(ale_cs), pointer :: CS !< module control structure
362 
363  ! Deallocate memory used for the regridding
364  call end_remapping( cs%remapCS )
365  call end_regridding( cs%regridCS )
366 
367  deallocate(cs)
368 
369 end subroutine ale_end
370 
371 !> Takes care of (1) building a new grid and (2) remapping all variables between
372 !! the old grid and the new grid. The creation of the new grid can be based
373 !! on z coordinates, target interface densities, sigma coordinates or any
374 !! arbitrary coordinate system.
375 subroutine ale_main( G, GV, h, u, v, tv, Reg, CS, dt, frac_shelf_h)
376  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
377  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
378  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after last time step (m or Pa)
379  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: u !< Zonal velocity field (m/s)
380  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: v !< Meridional velocity field (m/s)
381  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
382  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
383  type(ale_cs), pointer :: CS !< Regridding parameters and options
384  real, optional, intent(in) :: dt !< Time step between calls to ALE_main()
385  real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage
386  ! Local variables
387  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
388  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step (m or Pa)
389  integer :: nk, i, j, k, isc, iec, jsc, jec
390  logical :: ice_shelf
391 
392  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
393 
394  ice_shelf = .false.
395  if (present(frac_shelf_h)) then
396  if (associated(frac_shelf_h)) ice_shelf = .true.
397  endif
398 
399  if (cs%show_call_tree) call calltree_enter("ALE_main(), MOM_ALE.F90")
400 
401  if (present(dt)) then
402  call ale_update_regrid_weights( dt, cs )
403  endif
404  dzregrid(:,:,:) = 0.0
405 
406  ! Build new grid. The new grid is stored in h_new. The old grid is h.
407  ! Both are needed for the subsequent remapping of variables.
408  if (ice_shelf) then
409  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, frac_shelf_h)
410  else
411  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid)
412  endif
413 
414  call check_grid( g, gv, h, 0. )
415 
416  if (cs%show_call_tree) call calltree_waypoint("new grid generated (ALE_main)")
417 
418  ! Remap all variables from old grid h onto new grid h_new
419 
420  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, -dzregrid, &
421  u, v, cs%show_call_tree, dt )
422 
423  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_main)")
424 
425  ! Override old grid with new one. The new grid 'h_new' is built in
426  ! one of the 'build_...' routines above.
427 !$OMP parallel do default(none) shared(isc,iec,jsc,jec,nk,h,h_new,CS)
428  do k = 1,nk
429  do j = jsc-1,jec+1 ; do i = isc-1,iec+1
430  h(i,j,k) = h_new(i,j,k)
431  enddo ; enddo
432  enddo
433 
434  if (cs%show_call_tree) call calltree_leave("ALE_main()")
435 
436  if (cs%id_dzRegrid>0 .and. present(dt)) call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
437 
438 
439 end subroutine ale_main
440 
441 !> Takes care of (1) building a new grid and (2) remapping all variables between
442 !! the old grid and the new grid. The creation of the new grid can be based
443 !! on z coordinates, target interface densities, sigma coordinates or any
444 !! arbitrary coordinate system.
445 subroutine ale_main_offline( G, GV, h, tv, Reg, CS, dt)
446  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
447  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
448  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after last time step (m or Pa)
449  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
450  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
451  type(ale_cs), pointer :: CS !< Regridding parameters and options
452  real, optional, intent(in) :: dt !< Time step between calls to ALE_main()
453  ! Local variables
454  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
455  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step (m or Pa)
456  integer :: nk, i, j, k, isc, iec, jsc, jec
457 
458  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
459 
460  if (cs%show_call_tree) call calltree_enter("ALE_main_offline(), MOM_ALE.F90")
461 
462  if (present(dt)) then
463  call ale_update_regrid_weights( dt, cs )
464  endif
465  dzregrid(:,:,:) = 0.0
466 
467  ! Build new grid. The new grid is stored in h_new. The old grid is h.
468  ! Both are needed for the subsequent remapping of variables.
469  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid )
470 
471  call check_grid( g, gv, h, 0. )
472 
473  if (cs%show_call_tree) call calltree_waypoint("new grid generated (ALE_main)")
474 
475  ! Remap all variables from old grid h onto new grid h_new
476 
477  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree, dt=dt )
478 
479  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_main)")
480 
481  ! Override old grid with new one. The new grid 'h_new' is built in
482  ! one of the 'build_...' routines above.
483 !$OMP parallel do default(none) shared(isc,iec,jsc,jec,nk,h,h_new,CS)
484  do k = 1,nk
485  do j = jsc-1,jec+1 ; do i = isc-1,iec+1
486  h(i,j,k) = h_new(i,j,k)
487  enddo ; enddo
488  enddo
489 
490  if (cs%show_call_tree) call calltree_leave("ALE_main()")
491  if (cs%id_dzRegrid>0 .and. present(dt)) call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
492 
493 end subroutine ale_main_offline
494 
495 !> Regrid/remap stored fields used for offline tracer integrations. These input fields are assumed to have
496 !! the same layer thicknesses at the end of the last offline interval (which should be a Zstar grid). This
497 !! routine builds a grid on the runtime specified vertical coordinate
498 subroutine ale_offline_inputs(CS, G, GV, h, tv, Reg, uhtr, vhtr, Kd, debug)
499  type(ale_cs), pointer :: CS !< Regridding parameters and options
500  type(ocean_grid_type), intent(in ) :: G !< Ocean grid informations
501  type(verticalgrid_type), intent(in ) :: GV !< Ocean vertical grid structure
502  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Layer thicknesses
503  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
504  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
505  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr !< Zonal mass fluxes
506  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: vhtr !< Meridional mass fluxes
507  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: Kd !< Input diffusivites
508  logical, intent(in ) :: debug !< If true, then turn checksums
509  ! Local variables
510  integer :: nk, i, j, k, isc, iec, jsc, jec
511  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new ! Layer thicknesses after regridding
512  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
513  real, dimension(SZK_(GV)) :: h_src
514  real, dimension(SZK_(GV)) :: h_dest, uh_dest
515  real, dimension(SZK_(GV)) :: temp_vec
516 
517  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
518  dzregrid(:,:,:) = 0.0
519  h_new(:,:,:) = 0.0
520 
521  if (debug) call mom_tracer_chkinv("Before ALE_offline_inputs", g, h, reg%Tr, reg%ntr)
522 
523  ! Build new grid from the Zstar state onto the requested vertical coordinate. The new grid is stored
524  ! in h_new. The old grid is h. Both are needed for the subsequent remapping of variables. Convective
525  ! adjustment right now is not used because it is unclear what to do with vanished layers
526  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, conv_adjust = .false. )
527  call check_grid( g, gv, h_new, 0. )
528  if (cs%show_call_tree) call calltree_waypoint("new grid generated (ALE_offline_inputs)")
529 
530  ! Remap all variables from old grid h onto new grid h_new
531  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree )
532  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_inputs)")
533 
534  ! Reintegrate mass transports from Zstar to the offline vertical coordinate
535  do j=jsc,jec ; do i=g%iscB,g%iecB
536  if (g%mask2dCu(i,j)>0.) then
537  h_src(:) = 0.5 * (h(i,j,:) + h(i+1,j,:))
538  h_dest(:) = 0.5 * (h_new(i,j,:) + h_new(i+1,j,:))
539  call reintegrate_column(nk, h_src, uhtr(i,j,:), nk, h_dest, 0., temp_vec)
540  uhtr(i,j,:) = temp_vec
541  endif
542  enddo ; enddo
543  do j=g%jscB,g%jecB ; do i=isc,iec
544  if (g%mask2dCv(i,j)>0.) then
545  h_src(:) = 0.5 * (h(i,j,:) + h(i,j+1,:))
546  h_dest(:) = 0.5 * (h_new(i,j,:) + h_new(i,j+1,:))
547  call reintegrate_column(nk, h_src, vhtr(i,j,:), nk, h_dest, 0., temp_vec)
548  vhtr(i,j,:) = temp_vec
549  endif
550  enddo ; enddo
551 
552  do j = jsc,jec ; do i=isc,iec
553  if (g%mask2dT(i,j)>0.) then
554  if (check_column_integrals(nk, h_src, nk, h_dest)) then
555  call mom_error(fatal, "ALE_offline_inputs: Kd interpolation columns do not match")
556  endif
557  call interpolate_column(nk, h(i,j,:), kd(i,j,:), nk, h_new(i,j,:), 0., kd(i,j,:))
558  endif
559  enddo ; enddo;
560 
561  call ale_remap_scalar(cs%remapCS, g, gv, nk, h, tv%T, h_new, tv%T)
562  call ale_remap_scalar(cs%remapCS, g, gv, nk, h, tv%S, h_new, tv%S)
563 
564  if (debug) call mom_tracer_chkinv("After ALE_offline_inputs", g, h_new, reg%Tr, reg%ntr)
565 
566  ! Copy over the new layer thicknesses
567  do k = 1,nk ; do j = jsc-1,jec+1 ; do i = isc-1,iec+1
568  h(i,j,k) = h_new(i,j,k)
569  enddo ; enddo ; enddo
570 
571  if (cs%show_call_tree) call calltree_leave("ALE_offline_inputs()")
572 end subroutine ale_offline_inputs
573 
574 
575 !> Remaps all tracers from h onto h_target. This is intended to be called when tracers
576 !! are done offline. In the case where transports don't quite conserve, we still want to
577 !! make sure that layer thicknesses offline do not drift too far away from the online model
578 subroutine ale_offline_tracer_final( G, GV, h, tv, h_target, Reg, CS)
579  type(ocean_grid_type), intent(in) :: G !< Ocean grid informations
580  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
581  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after
582  !! last time step (m or Pa)
583  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure
584  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h_target !< Current 3D grid obtained after
585  !! last time step (m or Pa)
586  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
587  type(ale_cs), pointer :: CS !< Regridding parameters and options
588  ! Local variables
589 
590  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid !< The change in grid interface positions
591  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new !< Regridded target thicknesses
592  integer :: nk, i, j, k, isc, iec, jsc, jec
593 
594  nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
595 
596  if (cs%show_call_tree) call calltree_enter("ALE_offline_tracer_final(), MOM_ALE.F90")
597  ! Need to make sure that h_target is consistent with the current offline ALE confiuration
598  call regridding_main( cs%remapCS, cs%regridCS, g, gv, h_target, tv, h_new, dzregrid )
599  call check_grid( g, gv, h_target, 0. )
600 
601 
602  if (cs%show_call_tree) call calltree_waypoint("Source and target grids checked (ALE_offline_tracer_final)")
603 
604  ! Remap all variables from old grid h onto new grid h_new
605 
606  call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree )
607 
608  if (cs%show_call_tree) call calltree_waypoint("state remapped (ALE_offline_tracer_final)")
609 
610  ! Override old grid with new one. The new grid 'h_new' is built in
611  ! one of the 'build_...' routines above.
612  !$OMP parallel do default(shared)
613  do k = 1,nk
614  do j = jsc-1,jec+1 ; do i = isc-1,iec+1
615  h(i,j,k) = h_new(i,j,k)
616  enddo ; enddo
617  enddo
618  if (cs%show_call_tree) call calltree_leave("ALE_offline_tracer_final()")
619 end subroutine ale_offline_tracer_final
620 
621 !> Check grid for negative thicknesses
622 subroutine check_grid( G, GV, h, threshold )
623  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
624  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
625  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Current 3D grid obtained after the last time step (H units)
626  real, intent(in) :: threshold !< Value below which to flag issues (H units)
627  ! Local variables
628  integer :: i, j
629 
630  do j = g%jsc,g%jec ; do i = g%isc,g%iec
631  if (g%mask2dT(i,j)>0.) then
632  if (minval(h(i,j,:)) < threshold) then
633  write(0,*) 'check_grid: i,j=',i,j,'h(i,j,:)=',h(i,j,:)
634  if (threshold <= 0.) then
635  call mom_error(fatal,"MOM_ALE, check_grid: negative thickness encountered.")
636  else
637  call mom_error(fatal,"MOM_ALE, check_grid: too tiny thickness encountered.")
638  endif
639  endif
640  endif
641  enddo ; enddo
642 
643 
644 end subroutine check_grid
645 
646 !> Generates new grid
647 subroutine ale_build_grid( G, GV, regridCS, remapCS, h, tv, debug, frac_shelf_h )
648  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
649  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
650  type(regridding_cs), intent(in) :: regridCS !< Regridding parameters and options
651  type(remapping_cs), intent(in) :: remapCS !< Remapping parameters and options
652  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamical variable structure
653  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the last time step (m or Pa)
654  logical, optional, intent(in) :: debug !< If true, show the call tree
655  real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage
656  ! Local variables
657  integer :: nk, i, j, k
658  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions
659  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new ! The new grid thicknesses
660  logical :: show_call_tree, use_ice_shelf
661 
662  show_call_tree = .false.
663  if (present(debug)) show_call_tree = debug
664  if (show_call_tree) call calltree_enter("ALE_build_grid(), MOM_ALE.F90")
665  use_ice_shelf = .false.
666  if (present(frac_shelf_h)) then
667  if (associated(frac_shelf_h)) use_ice_shelf = .true.
668  endif
669 
670  ! Build new grid. The new grid is stored in h_new. The old grid is h.
671  ! Both are needed for the subsequent remapping of variables.
672  if (use_ice_shelf) then
673  call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid, frac_shelf_h )
674  else
675  call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid )
676  endif
677 
678  ! Override old grid with new one. The new grid 'h_new' is built in
679  ! one of the 'build_...' routines above.
680 !$OMP parallel do default(none) shared(G,h,h_new)
681  do j = g%jsc,g%jec ; do i = g%isc,g%iec
682  if (g%mask2dT(i,j)>0.) h(i,j,:) = h_new(i,j,:)
683  enddo ; enddo
684 
685  if (show_call_tree) call calltree_leave("ALE_build_grid()")
686 end subroutine ale_build_grid
687 
688 !> For a state-based coordinate, accelerate the process of regridding by
689 !! repeatedly applying the grid calculation algorithm
690 subroutine ale_regrid_accelerated(CS, G, GV, h_orig, tv, n, h_new, u, v)
691  type(ale_cs), intent(in) :: CS !< ALE control structure
692  type(ocean_grid_type), intent(inout) :: G !< Ocean grid
693  type(verticalgrid_type), intent(in) :: GV !< Vertical grid
694  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_orig !< Original thicknesses
695  type(thermo_var_ptrs), intent(inout) :: tv !< Thermo vars (T/S/EOS)
696  integer, intent(in) :: n !< Number of times to regrid
697  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: h_new !< Thicknesses after regridding
698  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: u !< Zonal velocity
699  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: v !< Meridional velocity
700 
701  ! Local variables
702  integer :: i, j, k, nz
703  type(thermo_var_ptrs) :: tv_local ! local/intermediate temp/salt
704  type(group_pass_type) :: pass_T_S_h ! group pass if the coordinate has a stencil
705  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h ! A working copy of layer thickesses
706  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), target :: T, S ! temporary state
707  ! we have to keep track of the total dzInterface if for some reason
708  ! we're using the old remapping algorithm for u/v
709  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzInterface, dzIntTotal
710 
711  nz = gv%ke
712 
713  ! initial total interface displacement due to successive regridding
714  dzinttotal(:,:,:) = 0.
715 
716  call create_group_pass(pass_t_s_h, t, g%domain)
717  call create_group_pass(pass_t_s_h, s, g%domain)
718  call create_group_pass(pass_t_s_h, h, g%domain)
719 
720  ! copy original temp/salt and set our local tv_pointers to them
721  tv_local = tv
722  t(:,:,:) = tv%T(:,:,:)
723  s(:,:,:) = tv%S(:,:,:)
724  tv_local%T => t
725  tv_local%S => s
726 
727  ! get local copy of thickness
728  h(:,:,:) = h_orig(:,:,:)
729 
730  do k = 1, n
731  call do_group_pass(pass_t_s_h, g%domain)
732 
733  ! generate new grid
734  call regridding_main(cs%remapCS, cs%regridCS, g, gv, h, tv_local, h_new, dzinterface)
735  dzinttotal(:,:,:) = dzinttotal(:,:,:) + dzinterface(:,:,:)
736 
737  ! remap from original grid onto new grid
738  ! we need to use remapping_core because there isn't a tracer registry set up in
739  ! the state initialization routine
740  do j = g%jsc,g%jec ; do i = g%isc,g%iec
741  call remapping_core_h(cs%remapCS, nz, h_orig(i,j,:), tv%S(i,j,:), nz, h_new(i,j,:), tv_local%S(i,j,:))
742  call remapping_core_h(cs%remapCS, nz, h_orig(i,j,:), tv%T(i,j,:), nz, h_new(i,j,:), tv_local%T(i,j,:))
743  enddo ; enddo
744 
745 
746  h(:,:,:) = h_new(:,:,:)
747  enddo
748 
749  ! save the final temp/salt
750  tv%S(:,:,:) = s(:,:,:)
751  tv%T(:,:,:) = t(:,:,:)
752 
753  ! remap velocities
754  call remap_all_state_vars(cs%remapCS, cs, g, gv, h_orig, h_new, null(), dzinttotal, u, v)
755 end subroutine ale_regrid_accelerated
756 
757 !> This routine takes care of remapping all variable between the old and the
758 !! new grids. When velocity components need to be remapped, thicknesses at
759 !! velocity points are taken to be arithmetic averages of tracer thicknesses.
760 !! This routine is called during initialization of the model at time=0, to
761 !! remap initiali conditions to the model grid. It is also called during a
762 !! time step to update the state.
763 subroutine remap_all_state_vars(CS_remapping, CS_ALE, G, GV, h_old, h_new, Reg, dxInterface, u, v, debug, dt)
764  type(remapping_cs), intent(in) :: CS_remapping !< Remapping control structure
765  type(ale_cs), intent(in) :: CS_ALE !< ALE control structure
766  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
767  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
768  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_old !< Thickness of source grid (m or Pa)
769  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_new !< Thickness of destination grid (m or Pa)
770  type(tracer_registry_type), pointer :: Reg !< Tracer registry structure
771  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1),optional, intent(in) :: dxInterface !< Change in interface position (Hm or Pa)
772  real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), optional, intent(inout) :: u !< Zonal velocity component (m/s)
773  real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), optional, intent(inout) :: v !< Meridional velocity component (m/s)
774  logical, optional, intent(in) :: debug !< If true, show the call tree
775  real, optional, intent(in) :: dt !< time step for diagnostics
776  ! Local variables
777  integer :: i, j, k, m
778  integer :: nz, ntr
779  real, dimension(GV%ke+1) :: dx
780  real, dimension(GV%ke) :: h1, u_column
781  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: work_conc
782  real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: work_cont
783  real, dimension(SZI_(G), SZJ_(G)) :: work_2d
784  real :: Idt, ppt2mks
785  real, dimension(GV%ke) :: h2
786  logical :: show_call_tree
787 
788  show_call_tree = .false.
789  if (present(debug)) show_call_tree = debug
790  if (show_call_tree) call calltree_enter("remap_all_state_vars(), MOM_ALE.F90")
791 
792  ! If remap_uv_using_old_alg is .true. and u or v is requested, then we must have dxInterface. Otherwise,
793  ! u and v can be remapped without dxInterface
794  if ( .not. present(dxinterface) .and. (cs_ale%remap_uv_using_old_alg .and. (present(u) .or. present(v))) ) then
795  call mom_error(fatal, "remap_all_state_vars: dxInterface must be present if using old algorithm and u/v are to"// &
796  "be remapped")
797  endif
798 
799  nz = gv%ke
800  ppt2mks = 0.001
801 
802  if (associated(reg)) then
803  ntr = reg%ntr
804  else
805  ntr = 0
806  endif
807 
808  if(present(dt)) then
809  work_conc(:,:,:) = 0.0
810  work_cont(:,:,:) = 0.0
811  work_2d(:,:) = 0.0
812  idt = 1.0/dt
813  endif
814 
815  ! Remap tracer
816 !$OMP parallel default(none) shared(G,GV,h_old,h_new,dxInterface,CS_remapping,nz,Reg,u,v,ntr,show_call_tree, &
817 !$OMP dt,CS_ALE,work_conc,work_cont,work_2d,Idt,ppt2mks) &
818 !$OMP private(h1,h2,dx,u_column)
819  if (ntr>0) then
820  if (show_call_tree) call calltree_waypoint("remapping tracers (remap_all_state_vars)")
821 !$OMP do
822  do m=1,ntr ! For each tracer
823 
824  do j = g%jsc,g%jec
825  do i = g%isc,g%iec
826 
827  if (g%mask2dT(i,j)>0.) then
828 
829  ! Build the start and final grids
830  h1(:) = h_old(i,j,:)
831  h2(:) = h_new(i,j,:)
832  call remapping_core_h(cs_remapping, nz, h1, reg%Tr(m)%t(i,j,:), nz, h2, u_column)
833 
834  ! Intermediate steps for tendency of tracer concentration and tracer content.
835  ! Note: do not merge the two if-tests, since do_tendency_diag(:) is not
836  ! allocated during the time=0 initialization call to this routine.
837  if(present(dt)) then
838  if(cs_ale%do_tendency_diag(m)) then
839  do k=1,gv%ke
840  work_conc(i,j,k) = (u_column(k) - reg%Tr(m)%t(i,j,k) ) * idt
841  work_cont(i,j,k) = (u_column(k)*h2(k) - reg%Tr(m)%t(i,j,k)*h1(k)) * idt * gv%H_to_kg_m2
842  enddo
843  endif
844  endif
845 
846  ! update tracer concentration
847  reg%Tr(m)%t(i,j,:) = u_column(:)
848 
849  endif
850 
851  enddo ! i
852  enddo ! j
853 
854 
855  ! tendency diagnostics.
856  ! Note: do not merge the two if-tests if(present(dt)) and
857  ! if(CS_ALE%do_tendency_diag(m)). The reason is that
858  ! do_tendency_diag(:) is not allocated when this routine is called
859  ! during initialization (time=0). So need to keep the if-tests split.
860  if(present(dt)) then
861  if(cs_ale%do_tendency_diag(m)) then
862 
863  if(cs_ale%id_tracer_remap_tendency(m) > 0) then
864  call post_data(cs_ale%id_tracer_remap_tendency(m), work_conc, cs_ale%diag)
865  endif
866 
867  if (cs_ale%id_Htracer_remap_tendency(m) > 0 .or. cs_ale%id_Htracer_remap_tendency_2d(m) > 0) then
868  if(trim(reg%Tr(m)%name) == 'T') then
869  do k=1,gv%ke
870  do j = g%jsc,g%jec
871  do i = g%isc,g%iec
872  work_cont(i,j,k) = work_cont(i,j,k) * cs_ale%C_p
873  enddo
874  enddo
875  enddo
876  elseif(trim(reg%Tr(m)%name) == 'S') then
877  do k=1,gv%ke
878  do j = g%jsc,g%jec
879  do i = g%isc,g%iec
880  work_cont(i,j,k) = work_cont(i,j,k) * ppt2mks
881  enddo
882  enddo
883  enddo
884  endif
885  endif
886 
887  if (cs_ale%id_Htracer_remap_tendency(m) > 0) then
888  call post_data(cs_ale%id_Htracer_remap_tendency(m), work_cont, cs_ale%diag)
889  endif
890  if (cs_ale%id_Htracer_remap_tendency_2d(m) > 0) then
891  do j = g%jsc,g%jec
892  do i = g%isc,g%iec
893  work_2d(i,j) = 0.0
894  do k = 1,gv%ke
895  work_2d(i,j) = work_2d(i,j) + work_cont(i,j,k)
896  enddo
897  enddo
898  enddo
899  call post_data(cs_ale%id_Htracer_remap_tendency_2d(m), work_2d, cs_ale%diag)
900  endif
901 
902  endif
903  endif
904 
905  enddo ! m=1,ntr
906 
907  endif ! endif for ntr > 0
908 
909  if (show_call_tree) call calltree_waypoint("tracers remapped (remap_all_state_vars)")
910 
911  ! Remap u velocity component
912  if ( present(u) ) then
913 !$OMP do
914  do j = g%jsc,g%jec
915  do i = g%iscB,g%iecB
916  if (g%mask2dCu(i,j)>0.) then
917  ! Build the start and final grids
918  h1(:) = 0.5 * ( h_old(i,j,:) + h_old(i+1,j,:) )
919  if (cs_ale%remap_uv_using_old_alg) then
920  dx(:) = 0.5 * ( dxinterface(i,j,:) + dxinterface(i+1,j,:) )
921  do k = 1, nz
922  h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
923  enddo
924  else
925  h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i+1,j,:) )
926  endif
927  call remapping_core_h(cs_remapping, nz, h1, u(i,j,:), nz, h2, u_column)
928  u(i,j,:) = u_column(:)
929  endif
930  enddo
931  enddo
932  endif
933 
934  if (show_call_tree) call calltree_waypoint("u remapped (remap_all_state_vars)")
935 
936  ! Remap v velocity component
937  if ( present(v) ) then
938 !$OMP do
939  do j = g%jscB,g%jecB
940  do i = g%isc,g%iec
941  if (g%mask2dCv(i,j)>0.) then
942  ! Build the start and final grids
943  h1(:) = 0.5 * ( h_old(i,j,:) + h_old(i,j+1,:) )
944  if (cs_ale%remap_uv_using_old_alg) then
945  dx(:) = 0.5 * ( dxinterface(i,j,:) + dxinterface(i,j+1,:) )
946  do k = 1, nz
947  h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
948  enddo
949  else
950  h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i,j+1,:) )
951  endif
952  call remapping_core_h(cs_remapping, nz, h1, v(i,j,:), nz, h2, u_column)
953  v(i,j,:) = u_column(:)
954  endif
955  enddo
956  enddo
957  endif
958 !$OMP end parallel
959 
960  if (show_call_tree) call calltree_waypoint("v remapped (remap_all_state_vars)")
961  if (show_call_tree) call calltree_leave("remap_all_state_vars()")
962 
963 end subroutine remap_all_state_vars
964 
965 
966 !> Remaps a single scalar between grids described by thicknesses h_src and h_dst.
967 !! h_dst must be dimensioned as a model array with GV%ke layers while h_src can
968 !! have an arbitrary number of layers specified by nk_src.
969 subroutine ale_remap_scalar(CS, G, GV, nk_src, h_src, s_src, h_dst, s_dst, all_cells, old_remap )
970  type(remapping_cs), intent(in) :: CS !< Remapping control structure
971  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
972  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
973  integer, intent(in) :: nk_src !< Number of levels on source grid
974  real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: h_src !< Level thickness of source grid (m or Pa)
975  real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: s_src !< Scalar on source grid
976  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(in) :: h_dst !< Level thickness of destination grid (m or Pa)
977  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: s_dst !< Scalar on destination grid
978  logical, optional, intent(in) :: all_cells !< If false, only reconstruct for
979  !! non-vanished cells. Use all vanished
980  !! layers otherwise (default).
981  logical, optional, intent(in) :: old_remap !< If true, use the old "remapping_core_w"
982  !! method, otherwise use "remapping_core_h".
983  ! Local variables
984  integer :: i, j, k, n_points
985  real :: dx(gv%ke+1)
986  logical :: ignore_vanished_layers, use_remapping_core_w
987 
988  ignore_vanished_layers = .false.
989  if (present(all_cells)) ignore_vanished_layers = .not. all_cells
990  use_remapping_core_w = .false.
991  if (present(old_remap)) use_remapping_core_w = old_remap
992  n_points = nk_src
993 
994 !$OMP parallel default(none) shared(CS,G,GV,h_src,s_src,h_dst,s_dst &
995 !$OMP ,ignore_vanished_layers, use_remapping_core_w, nk_src ) &
996 !$OMP firstprivate(n_points,dx)
997 !$OMP do
998  do j = g%jsc,g%jec
999  do i = g%isc,g%iec
1000  if (g%mask2dT(i,j)>0.) then
1001  if (ignore_vanished_layers) then
1002  n_points = 0
1003  do k = 1, nk_src
1004  if (h_src(i,j,k)>0.) n_points = n_points + 1
1005  enddo
1006  s_dst(i,j,:) = 0.
1007  endif
1008  if (use_remapping_core_w) then
1009  call dzfromh1h2( n_points, h_src(i,j,1:n_points), gv%ke, h_dst(i,j,:), dx )
1010  call remapping_core_w(cs, n_points, h_src(i,j,1:n_points), s_src(i,j,1:n_points), gv%ke, dx, s_dst(i,j,:))
1011  else
1012  call remapping_core_h(cs, n_points, h_src(i,j,1:n_points), s_src(i,j,1:n_points), gv%ke, h_dst(i,j,:), s_dst(i,j,:))
1013  endif
1014  else
1015  s_dst(i,j,:) = 0.
1016  endif
1017  enddo
1018  enddo
1019 !$OMP end parallel
1020 
1021 end subroutine ale_remap_scalar
1022 
1023 
1024 !> Use plm reconstruction for pressure gradient (determine edge values)
1025 !! By using a PLM (limited piecewise linear method) reconstruction, this
1026 !! routine determines the edge values for the salinity and temperature
1027 !! within each layer. These edge values are returned and are used to compute
1028 !! the pressure gradient (by computing the densities).
1029 subroutine pressure_gradient_plm( CS, S_t, S_b, T_t, T_b, G, GV, tv, h )
1030  type(ocean_grid_type), intent(in) :: G !< ocean grid structure
1031  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
1032  type(ale_cs), intent(inout) :: CS !< module control structure
1033  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: S_t !< Salinity at the top edge of each layer
1034  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: S_b !< Salinity at the bottom edge of each layer
1035  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: T_t !< Temperature at the top edge of each layer
1036  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: T_b !< Temperature at the bottom edge of each layer
1037  type(thermo_var_ptrs), intent(in) :: tv !< thermodynamics structure
1038  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< layer thickness
1039 
1040  ! Local variables
1041  integer :: i, j, k
1042  real :: hTmp(gv%ke)
1043  real :: tmp(gv%ke)
1044  real, dimension(CS%nk,2) :: ppoly_linear_E !Edge value of polynomial
1045  real, dimension(CS%nk,CS%degree_linear+1) :: ppoly_linear_coefficients !Coefficients of polynomial
1046 
1047  ! NOTE: the variables 'CS%grid_generic' and 'CS%ppoly_linear' are declared at
1048  ! the module level.
1049 
1050  ! Determine reconstruction within each column
1051 !$OMP parallel do default(none) shared(G,GV,h,tv,CS,S_t,S_b,T_t,T_b) &
1052 !$OMP private(hTmp,ppoly_linear_E,ppoly_linear_coefficients,tmp)
1053  do j = g%jsc-1,g%jec+1
1054  do i = g%isc-1,g%iec+1
1055  ! Build current grid
1056  htmp(:) = h(i,j,:)*gv%H_to_m
1057  tmp(:) = tv%S(i,j,:)
1058  ! Reconstruct salinity profile
1059  ppoly_linear_e = 0.0
1060  ppoly_linear_coefficients = 0.0
1061  call plm_reconstruction( gv%ke, htmp, tmp, ppoly_linear_e, ppoly_linear_coefficients )
1062  if (cs%boundary_extrapolation_for_pressure) call &
1063  plm_boundary_extrapolation( gv%ke, htmp, tmp, ppoly_linear_e, ppoly_linear_coefficients )
1064 
1065  do k = 1,gv%ke
1066  s_t(i,j,k) = ppoly_linear_e(k,1)
1067  s_b(i,j,k) = ppoly_linear_e(k,2)
1068  end do
1069 
1070  ! Reconstruct temperature profile
1071  ppoly_linear_e = 0.0
1072  ppoly_linear_coefficients = 0.0
1073  tmp(:) = tv%T(i,j,:)
1074  call plm_reconstruction( gv%ke, htmp, tmp, ppoly_linear_e, ppoly_linear_coefficients )
1075  if (cs%boundary_extrapolation_for_pressure) call &
1076  plm_boundary_extrapolation( gv%ke, htmp, tmp, ppoly_linear_e, ppoly_linear_coefficients )
1077 
1078  do k = 1,gv%ke
1079  t_t(i,j,k) = ppoly_linear_e(k,1)
1080  t_b(i,j,k) = ppoly_linear_e(k,2)
1081  end do
1082 
1083  end do
1084  end do
1085 
1086 end subroutine pressure_gradient_plm
1087 
1088 
1089 !> Use ppm reconstruction for pressure gradient (determine edge values)
1090 !> By using a PPM (limited piecewise linear method) reconstruction, this
1091 !> routine determines the edge values for the salinity and temperature
1092 !> within each layer. These edge values are returned and are used to compute
1093 !> the pressure gradient (by computing the densities).
1094 subroutine pressure_gradient_ppm( CS, S_t, S_b, T_t, T_b, G, GV, tv, h )
1095  type(ocean_grid_type), intent(in) :: G !< ocean grid structure
1096  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
1097  type(ale_cs), intent(inout) :: CS !< module control structure
1098  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: S_t !< Salinity at top edge of each layer
1099  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: S_b !< Salinity at bottom edge of each layer
1100  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: T_t !< Temperature at the top edge of each layer
1101  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: T_b !< Temperature at the bottom edge of each layer
1102  type(thermo_var_ptrs), intent(in) :: tv !< ocean thermodynamics structure
1103  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< layer thickness
1104 
1105  ! Local variables
1106  integer :: i, j, k
1107  real :: hTmp(gv%ke)
1108  real :: tmp(gv%ke)
1109  real, dimension(CS%nk,2) :: &
1110  ppoly_parab_E !Edge value of polynomial
1111  real, dimension(CS%nk,CS%degree_parab+1) :: &
1112  ppoly_parab_coefficients !Coefficients of polynomial
1113 
1114 
1115  ! NOTE: the variables 'CS%grid_generic' and 'CS%ppoly_parab' are declared at
1116  ! the module level.
1117 
1118  ! Determine reconstruction within each column
1119 !$OMP parallel do default(none) shared(G,GV,h,tv,CS,S_t,S_b,T_t,T_b) &
1120 !$OMP private(hTmp,tmp,ppoly_parab_E,ppoly_parab_coefficients)
1121  do j = g%jsc-1,g%jec+1
1122  do i = g%isc-1,g%iec+1
1123 
1124  ! Build current grid
1125  htmp(:) = h(i,j,:) * gv%H_to_m
1126  tmp(:) = tv%S(i,j,:)
1127 
1128  ! Reconstruct salinity profile
1129  ppoly_parab_e = 0.0
1130  ppoly_parab_coefficients = 0.0
1131  call edge_values_implicit_h4( gv%ke, htmp, tmp, ppoly_parab_e )
1132  call ppm_reconstruction( gv%ke, htmp, tmp, ppoly_parab_e, ppoly_parab_coefficients )
1133  if (cs%boundary_extrapolation_for_pressure) call &
1134  ppm_boundary_extrapolation( gv%ke, htmp, tmp, ppoly_parab_e, ppoly_parab_coefficients )
1135 
1136  do k = 1,gv%ke
1137  s_t(i,j,k) = ppoly_parab_e(k,1)
1138  s_b(i,j,k) = ppoly_parab_e(k,2)
1139  end do
1140 
1141  ! Reconstruct temperature profile
1142  ppoly_parab_e = 0.0
1143  ppoly_parab_coefficients = 0.0
1144  tmp(:) = tv%T(i,j,:)
1145  call edge_values_implicit_h4( gv%ke, htmp, tmp, ppoly_parab_e )
1146  call ppm_reconstruction( gv%ke, htmp, tmp, ppoly_parab_e, ppoly_parab_coefficients )
1147  if (cs%boundary_extrapolation_for_pressure) call &
1148  ppm_boundary_extrapolation( gv%ke, htmp, tmp, ppoly_parab_e, ppoly_parab_coefficients )
1149 
1150  do k = 1,gv%ke
1151  t_t(i,j,k) = ppoly_parab_e(k,1)
1152  t_b(i,j,k) = ppoly_parab_e(k,2)
1153  end do
1154 
1155  end do
1156  end do
1157 
1158 end subroutine pressure_gradient_ppm
1159 
1160 
1161 !> pressure reconstruction logical
1162 logical function usepressurereconstruction(CS)
1163  type(ale_cs), pointer :: CS !< control structure
1164 
1165  if (associated(cs)) then
1166  usepressurereconstruction=cs%reconstructForPressure
1167  else
1169  endif
1170 
1171 end function usepressurereconstruction
1172 
1173 
1174 !> pressure reconstruction integer
1175 integer function pressurereconstructionscheme(CS)
1176  type(ale_cs), pointer :: CS !< control structure
1177 
1178  if (associated(cs)) then
1179  pressurereconstructionscheme=cs%pressureReconstructionScheme
1180  else
1182  endif
1183 
1184 end function pressurereconstructionscheme
1185 
1186 !> Initializes regridding for the main ALE algorithm
1187 subroutine ale_initregridding(GV, max_depth, param_file, mdl, regridCS)
1188  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
1189  real, intent(in) :: max_depth !< The maximum depth of the ocean, in m.
1190  type(param_file_type), intent(in) :: param_file !< parameter file
1191  character(len=*), intent(in) :: mdl !< Name of calling module
1192  type(regridding_cs), intent(out) :: regridCS !< Regridding parameters and work arrays
1193  ! Local variables
1194  character(len=30) :: coord_mode
1195 
1196  call get_param(param_file, mdl, "REGRIDDING_COORDINATE_MODE", coord_mode, &
1197  "Coordinate mode for vertical regridding.\n"//&
1198  "Choose among the following possibilities:\n"//&
1199  trim(regriddingcoordinatemodedoc), &
1200  default=default_coordinate_mode, fail_if_missing=.true.)
1201 
1202  call initialize_regridding(regridcs, gv, max_depth, param_file, mdl, coord_mode, '', '')
1203 
1204 end subroutine ale_initregridding
1205 
1206 !> Query the target coordinate interfaces positions
1207 function ale_getcoordinate( CS )
1208  type(ale_cs), pointer :: CS !< module control structure
1209 
1210  real, dimension(CS%nk+1) :: ALE_getCoordinate
1211  ale_getcoordinate(:) = getcoordinateinterfaces( cs%regridCS )
1212 
1213 end function ale_getcoordinate
1214 
1215 
1216 !> Query the target coordinate units
1217 function ale_getcoordinateunits( CS )
1218  type(ale_cs), pointer :: CS !< module control structure
1219 
1220  character(len=20) :: ALE_getCoordinateUnits
1221 
1222  ale_getcoordinateunits = getcoordinateunits( cs%regridCS )
1223 
1224 end function ale_getcoordinateunits
1225 
1226 
1227 !> Returns true if initial conditions should be regridded and remapped
1228 logical function ale_remap_init_conds( CS )
1229  type(ale_cs), pointer :: CS !< module control structure
1230 
1231  ale_remap_init_conds = .false.
1232  if (associated(cs)) ale_remap_init_conds = cs%remap_after_initialization
1233 end function ale_remap_init_conds
1234 
1235 !> Updates the weights for time filtering the new grid generated in regridding
1236 subroutine ale_update_regrid_weights( dt, CS )
1237  real, intent(in) :: dt !< Time-step used between ALE calls
1238  type(ale_cs), pointer :: CS !< ALE control structure
1239  ! Local variables
1240  real :: w ! An implicit weighting estimate.
1241 
1242  if (associated(cs)) then
1243  w = 0.0
1244  if (cs%regrid_time_scale > 0.0) then
1245  w = cs%regrid_time_scale / (cs%regrid_time_scale + dt)
1246  endif
1247  call set_regrid_params(cs%regridCS, old_grid_weight=w)
1248  endif
1249 
1250 end subroutine ale_update_regrid_weights
1251 
1252 !> Update the vertical grid type with ALE information.
1253 !! This subroutine sets information in the verticalGrid_type to be
1254 !! consistent with the use of ALE mode.
1255 subroutine ale_updateverticalgridtype( CS, GV )
1256  type(ale_cs), pointer :: CS ! module control structure
1257  type(verticalgrid_type), pointer :: GV ! vertical grid information
1258 
1259  integer :: nk
1260 
1261  nk = gv%ke
1262  gv%sInterface(1:nk+1) = getcoordinateinterfaces( cs%regridCS )
1263  gv%sLayer(1:nk) = 0.5*( gv%sInterface(1:nk) + gv%sInterface(2:nk+1) )
1264  gv%zAxisUnits = getcoordinateunits( cs%regridCS )
1265  gv%zAxisLongName = getcoordinateshortname( cs%regridCS )
1266  gv%direction = -1 ! Because of ferret in z* mode. Need method to set
1267  ! as function of coordinae mode.
1268 
1269 end subroutine ale_updateverticalgridtype
1270 
1271 
1272 !> Write the vertical coordinate information into a file.
1273 !! This subroutine writes out a file containing any available data related
1274 !! to the vertical grid used by the MOM ocean model when in ALE mode.
1275 subroutine ale_writecoordinatefile( CS, GV, directory )
1276  type(ale_cs), pointer :: CS !< module control structure
1277  type(verticalgrid_type), intent(in) :: GV !< ocean vertical grid structure
1278  character(len=*), intent(in) :: directory !< directory for writing grid info
1279 
1280  character(len=240) :: filepath
1281  type(vardesc) :: vars(2)
1282  type(fieldtype) :: fields(2)
1283  integer :: unit
1284  real :: ds(gv%ke), dsi(gv%ke+1)
1285 
1286  filepath = trim(directory) // trim("Vertical_coordinate")
1287  ds(:) = getcoordinateresolution( cs%regridCS )
1288  dsi(1) = 0.5*ds(1)
1289  dsi(2:gv%ke) = 0.5*( ds(1:gv%ke-1) + ds(2:gv%ke) )
1290  dsi(gv%ke+1) = 0.5*ds(gv%ke)
1291 
1292  vars(1) = var_desc('ds', getcoordinateunits( cs%regridCS ), &
1293  'Layer Coordinate Thickness','1','L','1')
1294  vars(2) = var_desc('ds_interface', getcoordinateunits( cs%regridCS ), &
1295  'Layer Center Coordinate Separation','1','i','1')
1296 
1297  call create_file(unit, trim(filepath), vars, 2, fields, single_file, gv=gv)
1298  call write_field(unit, fields(1), ds)
1299  call write_field(unit, fields(2), dsi)
1300  call close_file(unit)
1301 
1302 end subroutine ale_writecoordinatefile
1303 
1304 
1305 !> Set h to coordinate values for fixed coordinate systems
1306 subroutine ale_initthicknesstocoord( CS, G, GV, h )
1307  type(ale_cs), intent(inout) :: CS !< module control structure
1308  type(ocean_grid_type), intent(in) :: G !< module grid structure
1309  type(verticalgrid_type), intent(in) :: GV !< Ocean vertical grid structure
1310  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: h !< layer thickness
1311 
1312  ! Local variables
1313  integer :: i, j, k
1314 
1315  do j = g%jsd,g%jed ; do i = g%isd,g%ied
1316  h(i,j,:) = getstaticthickness( cs%regridCS, 0., g%bathyT(i,j) )
1317  enddo; enddo
1318 
1319 end subroutine ale_initthicknesstocoord
1320 
1321 end module mom_ale
subroutine, public set_regrid_max_depths(CS, max_depths, units_to_H)
Set maximum interface depths based on a vector of input values.
integer function coordinatemode(string)
Parse a string parameter specifying the coordinate mode and return the appropriate enumerated integer...
subroutine, public ale_writecoordinatefile(CS, GV, directory)
Write the vertical coordinate information into a file. This subroutine writes out a file containing a...
Definition: MOM_ALE.F90:1276
logical, parameter, public regriddingdefaultboundaryextrapolation
Provides kernels for single-column interpolation, re-integration (re-mapping of integrated quantities...
real function, dimension(nk), public uniformresolution(nk, coordMode, maxDepth, rhoLight, rhoHeavy)
type(vardesc) function, public var_desc(name, units, longname, hor_grid, z_grid, t_grid, cmor_field_name, cmor_units, conversion, caller)
Returns a vardesc type whose elements have been filled with the provided fields. The argument name is...
Definition: MOM_io.F90:585
subroutine, public edge_values_implicit_h4(N, h, u, edge_values)
real, parameter, public regriddingdefaultminthickness
logical function, public check_column_integrals(nk_1, field_1, nk_2, field_2, missing_value)
Returns false if the column integrals of two given quantities are within roundoff of each other...
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 ha...
Definition: MOM_ALE.F90:499
This module contains the main regridding routines. Regridding comprises two steps: (1) Interpolation ...
Definition: MOM_ALE.F90:7
character(len=20) function, public getcoordinateunits(CS)
integer, parameter pressure_reconstruction_plm
Definition: regrid_defs.F90:16
character(len=3), public remappingdefaultscheme
Default remapping method.
logical function, public usepressurereconstruction(CS)
pressure reconstruction logical
Definition: MOM_ALE.F90:1163
integer function, public extract_integer(string, separators, n, missing_value)
Returns the integer corresponding to the nth word in the argument.
subroutine, public ale_build_grid(G, GV, regridCS, remapCS, h, tv, debug, frac_shelf_h)
Generates new grid.
Definition: MOM_ALE.F90:648
The following data type a list of diagnostic fields an their variants, as well as variables that cont...
Calculates density of sea water from T, S and P.
Definition: MOM_EOS.F90:45
subroutine, public p1m_boundary_extrapolation(N, h, u, ppoly_E, ppoly_coefficients)
real function, dimension(cs%nk+1), public ale_getcoordinate(CS)
Query the target coordinate interfaces positions.
Definition: MOM_ALE.F90:1208
subroutine, public do_group_pass(group, MOM_dom)
real function, dimension(cs%nk), public getcoordinateresolution(CS)
subroutine, public inflate_vanished_layers_old(CS, G, GV, h)
Generates vertical grids as part of the ALE algorithm.
character(len=256), public remappingschemesdoc
Documentation for external callers.
Provides column-wise vertical remapping functions.
character(len= *), parameter, public regriddingcoordinatemodedoc
Documentation for coordinate options.
subroutine, public ale_initthicknesstocoord(CS, G, GV, h)
Set h to coordinate values for fixed coordinate systems.
Definition: MOM_ALE.F90:1307
subroutine, public ale_register_diags(Time, G, diag, C_p, Reg, CS)
Initialize diagnostics for the ALE module.
Definition: MOM_ALE.F90:261
subroutine, public calltree_leave(mesg)
Writes a message about leaving a subroutine if call tree reporting is active.
Provides functions used with the Piecewise-Parabolic-Method in the vertical ALE algorithm.
This module contains I/O framework code.
Definition: MOM_io.F90:2
subroutine, public ale_regrid_accelerated(CS, G, GV, h_orig, tv, n, h_new, u, v)
For a state-based coordinate, accelerate the process of regridding by repeatedly applying the grid ca...
Definition: MOM_ALE.F90:691
subroutine, public reintegrate_column(nsrc, h_src, uh_src, ndest, h_dest, missing_value, uh_dest)
Conservatively calculate integrated data, uh_dest, on grid h_dest, from layer-integrated data...
subroutine, public ale_updateverticalgridtype(CS, GV)
Update the vertical grid type with ALE information. This subroutine sets information in the verticalG...
Definition: MOM_ALE.F90:1256
subroutine, public ale_end(CS)
End of regridding (memory deallocation). This routine is typically called (from MOM_end in file MOM...
Definition: MOM_ALE.F90:361
Container for remapping parameters.
subroutine, public remapping_core_w(CS, n0, h0, u0, n1, dx, u1)
Remaps column of values u0 on grid h0 to implied grid h1 where the interfaces of h1 differ from those...
subroutine, public p1m_interpolation(N, h, u, ppoly_E, ppoly_coefficients)
subroutine, public pressure_gradient_ppm(CS, S_t, S_b, T_t, T_b, G, GV, tv, h)
Use ppm reconstruction for pressure gradient (determine edge values) By using a PPM (limited piecewis...
Definition: MOM_ALE.F90:1095
character(len=20) function, public getcoordinateshortname(CS)
subroutine, public end_regridding(CS)
Deallocation of regridding memory.
subroutine, public ppm_reconstruction(N, h, u, ppoly_E, ppoly_coefficients)
Builds quadratic polynomials coefficients from cell mean and edge values.
subroutine, public calltree_waypoint(mesg, n)
Writes a message about reaching a milestone if call tree reporting is active.
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
subroutine check_grid(G, GV, h, threshold)
Check grid for negative thicknesses.
Definition: MOM_ALE.F90:623
logical function, public ale_remap_init_conds(CS)
Returns true if initial conditions should be regridded and remapped.
Definition: MOM_ALE.F90:1229
character(len=len(input_string)) function, public uppercase(input_string)
character(len=20) function, public ale_getcoordinateunits(CS)
Query the target coordinate units.
Definition: MOM_ALE.F90:1218
Regridding control structure.
subroutine, public p3m_interpolation(N, h, u, ppoly_E, ppoly_S, ppoly_coefficients)
subroutine, public set_regrid_params(CS, boundary_extrapolation, min_thickness, old_grid_weight, interp_scheme, depth_of_time_filter_shallow, depth_of_time_filter_deep, compress_fraction, dz_min_surface, nz_fixed_surface, Rho_ML_avg_depth, nlay_ML_to_interior, fix_haloclines, halocline_filt_len, halocline_strat_tol, integrate_downward_for_e, adaptTimeRatio, adaptZoom, adaptZoomCoeff, adaptBuoyCoeff, adaptAlpha, adaptDoMin)
Can be used to set any of the parameters for MOM_regridding.
subroutine, public dzfromh1h2(n1, h1, n2, h2, dx)
Calculates the change in interface positions based on h1 and h2.
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.
Definition: MOM_ALE.F90:764
real function, dimension(cs%nk), public getstaticthickness(CS, SSH, depth)
subroutine, public set_target_densities_from_gv(GV, CS)
Set target densities based on the old Rlay variable.
Type to carry basic tracer information.
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...
Definition: MOM_ALE.F90:579
character(len=120) function, public extractword(string, n)
Returns the string corresponding to the nth word in the argument or "" if the string is not long enou...
integer function, public pressurereconstructionscheme(CS)
pressure reconstruction integer
Definition: MOM_ALE.F90:1176
real function, dimension(cs%nk+1), public getcoordinateinterfaces(CS)
Query the target coordinate interface positions.
subroutine, public plm_boundary_extrapolation(N, h, u, ppoly_E, ppoly_coefficients)
subroutine, public plm_reconstruction(N, h, u, ppoly_E, ppoly_coefficients)
subroutine, public regridding_main(remapCS, CS, G, GV, h, tv, h_new, dzInterface, frac_shelf_h, conv_adjust)
Provides subroutines for quantities specific to the equation of state.
Definition: MOM_EOS.F90:2
subroutine, public end_remapping(CS)
Destrcutor for remapping control structure.
logical function, public calltree_showquery()
Returns True, if the verbosity>=6 indicating to show the call tree.
Type for describing a variable, typically a tracer.
Definition: MOM_io.F90:51
subroutine, public adjustgridforintegrity(CS, G, GV, h)
Crudely adjust (initial) grid for integrity. This routine is typically called (from initialize_MOM in...
Definition: MOM_ALE.F90:347
subroutine, public remapping_core_h(CS, n0, h0, u0, n1, h1, u1)
Remaps column of values u0 on grid h0 to grid h1 assuming the top edge is aligned.
subroutine, public ale_initregridding(GV, max_depth, param_file, mdl, regridCS)
Initializes regridding for the main ALE algorithm.
Definition: MOM_ALE.F90:1188
character(len= *), parameter, public regriddinginterpschemedoc
subroutine, public ale_update_regrid_weights(dt, CS)
Updates the weights for time filtering the new grid generated in regridding.
Definition: MOM_ALE.F90:1237
subroutine, public setcoordinateresolution(dz, CS)
subroutine, public set_target_densities(CS, rho_int)
Set target densities based on vector of interface values.
subroutine, public mom_tracer_chkinv(mesg, G, h, Tr, ntr)
Calculates and prints the global inventory of all tracers in the registry.
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
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 ne...
Definition: MOM_ALE.F90:446
subroutine, public ppm_boundary_extrapolation(N, h, u, ppoly_E, ppoly_coefficients)
Contains constants for interpreting input parameters that control regridding.
subroutine, public ale_init(param_file, GV, max_depth, CS)
This routine is typically called (from initialize_MOM in file MOM.F90) before the main time integrati...
Definition: MOM_ALE.F90:138
subroutine, public pressure_gradient_plm(CS, S_t, S_b, T_t, T_b, G, GV, tv, h)
Use plm reconstruction for pressure gradient (determine edge values) By using a PLM (limited piecewis...
Definition: MOM_ALE.F90:1030
subroutine, public initialize_remapping(CS, remapping_scheme, boundary_extrapolation, check_reconstruction, check_remapping, force_bounds_in_subcell)
Constructor for remapping control structure.
ALE control structure.
Definition: MOM_ALE.F90:61
subroutine, public set_regrid_max_thickness(CS, max_h, units_to_H)
Set maximum layer thicknesses based on a vector of input values.
subroutine, public create_file(unit, filename, vars, novars, fields, threading, timeunit, G, dG, GV)
Routine creates a new NetCDF file. It also sets up structures that describe this file and variables t...
Definition: MOM_io.F90:82
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 dimensio...
Definition: MOM_ALE.F90:970
subroutine, public ale_main(G, GV, 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 ne...
Definition: MOM_ALE.F90:376
integer function, public register_diag_field(module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, cell_methods, x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
Returns the "diag_mediator" handle for a group (native, CMOR, z-coord, ...) of diagnostics derived fr...
subroutine, public mom_error(level, message, all_print)
subroutine, public p3m_boundary_extrapolation(N, h, u, ppoly_E, ppoly_S, ppoly_coefficients)
character(len= *), parameter, public regriddingdefaultinterpscheme
subroutine, public initialize_regridding(CS, GV, max_depth, param_file, mod, coord_mode, param_prefix, param_suffix)
Initialization and configures a regridding control structure based on customizable run-time parameter...
subroutine, public calltree_enter(mesg, n)
Writes a message about entering a subroutine if call tree reporting is active.
subroutine, public interpolate_column(nsrc, h_src, u_src, ndest, h_dest, missing_value, u_dest)
Linearly interpolate interface data, u_src, from grid h_src to a grid h_dest.