25 use mom_io,
only : create_file, write_field, close_file
29 use mom_regridding,
only : initialize_regridding, regridding_main, end_regridding
32 use mom_regridding,
only : set_target_densities_from_gv, set_target_densities
33 use mom_regridding,
only : regriddingcoordinatemodedoc, default_coordinate_mode
34 use mom_regridding,
only : regriddinginterpschemedoc, regriddingdefaultinterpscheme
38 use mom_regridding,
only : getcoordinateinterfaces, getcoordinateresolution
39 use mom_regridding,
only : getcoordinateunits, getcoordinateshortname
43 use mom_remapping,
only : remappingschemesdoc, remappingdefaultscheme
54 use plm_functions,
only : plm_reconstruction, plm_boundary_extrapolation
55 use plm_functions,
only : plm_extrapolate_slope, plm_monotonized_slope, plm_slope_wa
56 use ppm_functions,
only : ppm_reconstruction, ppm_boundary_extrapolation
58 implicit none ;
private 59 #include <MOM_memory.h> 64 logical :: remap_uv_using_old_alg
68 real :: regrid_time_scale
76 logical :: remap_after_initialization
78 logical :: answers_2018
82 logical :: show_call_tree
86 integer,
dimension(:),
allocatable :: id_tracer_remap_tendency
87 integer,
dimension(:),
allocatable :: id_htracer_remap_tendency
88 integer,
dimension(:),
allocatable :: id_htracer_remap_tendency_2d
89 logical,
dimension(:),
allocatable :: do_tendency_diag
90 integer :: id_dzregrid = -1
93 integer :: id_u_preale = -1
94 integer :: id_v_preale = -1
95 integer :: id_h_preale = -1
96 integer :: id_t_preale = -1
97 integer :: id_s_preale = -1
98 integer :: id_e_preale = -1
99 integer :: id_vert_remap_h = -1
100 integer :: id_vert_remap_h_tendency = -1
108 public ale_main_offline
109 public ale_offline_inputs
110 public ale_offline_tracer_final
111 public ale_build_grid
112 public ale_regrid_accelerated
113 public ale_remap_scalar
114 public ale_plm_edge_values
115 public ts_plm_edge_values
116 public ts_ppm_edge_values
117 public adjustgridforintegrity
118 public ale_initregridding
119 public ale_getcoordinate
120 public ale_getcoordinateunits
121 public ale_writecoordinatefile
122 public ale_updateverticalgridtype
123 public ale_initthicknesstocoord
124 public ale_update_regrid_weights
125 public ale_remap_init_conds
126 public ale_register_diags
139 subroutine ale_init( param_file, GV, US, max_depth, CS)
143 real,
intent(in) :: max_depth
144 type(
ale_cs),
pointer :: cs
147 real,
dimension(:),
allocatable :: dz
148 character(len=40) :: mdl =
"MOM_ALE" 149 character(len=80) :: string
150 real :: filter_shallow_depth, filter_deep_depth
151 logical :: default_2018_answers
152 logical :: check_reconstruction
153 logical :: check_remapping
154 logical :: force_bounds_in_subcell
155 logical :: local_logical
156 logical :: remap_boundary_extrap
158 if (
associated(cs))
then 159 call mom_error(warning,
"ALE_init called with an associated "// &
160 "control structure.")
165 cs%show_call_tree = calltree_showquery()
166 if (cs%show_call_tree)
call calltree_enter(
"ALE_init(), MOM_ALE.F90")
168 call get_param(param_file, mdl,
"REMAP_UV_USING_OLD_ALG", cs%remap_uv_using_old_alg, &
169 "If true, uses the old remapping-via-a-delta-z method for "//&
170 "remapping u and v. If false, uses the new method that remaps "//&
171 "between grids described by an old and new thickness.", &
175 call ale_initregridding(gv, us, max_depth, param_file, mdl, cs%regridCS)
178 call get_param(param_file, mdl,
"REMAPPING_SCHEME", string, &
179 "This sets the reconstruction scheme used "//&
180 "for vertical remapping for all variables. "//&
181 "It can be one of the following schemes: "//&
182 trim(remappingschemesdoc), default=remappingdefaultscheme)
183 call get_param(param_file, mdl,
"FATAL_CHECK_RECONSTRUCTIONS", check_reconstruction, &
184 "If true, cell-by-cell reconstructions are checked for "//&
185 "consistency and if non-monotonicity or an inconsistency is "//&
186 "detected then a FATAL error is issued.", default=.false.)
187 call get_param(param_file, mdl,
"FATAL_CHECK_REMAPPING", check_remapping, &
188 "If true, the results of remapping are checked for "//&
189 "conservation and new extrema and if an inconsistency is "//&
190 "detected then a FATAL error is issued.", default=.false.)
191 call get_param(param_file, mdl,
"REMAP_BOUND_INTERMEDIATE_VALUES", force_bounds_in_subcell, &
192 "If true, the values on the intermediate grid used for remapping "//&
193 "are forced to be bounded, which might not be the case due to "//&
194 "round off.", default=.false.)
195 call get_param(param_file, mdl,
"REMAP_BOUNDARY_EXTRAP", remap_boundary_extrap, &
196 "If true, values at the interfaces of boundary cells are "//&
197 "extrapolated instead of piecewise constant", default=.false.)
198 call get_param(param_file, mdl,
"DEFAULT_2018_ANSWERS", default_2018_answers, &
199 "This sets the default value for the various _2018_ANSWERS parameters.", &
201 call get_param(param_file, mdl,
"REMAPPING_2018_ANSWERS", cs%answers_2018, &
202 "If true, use the order of arithmetic and expressions that recover the "//&
203 "answers from the end of 2018. Otherwise, use updated and more robust "//&
204 "forms of the same expressions.", default=default_2018_answers)
205 call initialize_remapping( cs%remapCS, string, &
206 boundary_extrapolation=remap_boundary_extrap, &
207 check_reconstruction=check_reconstruction, &
208 check_remapping=check_remapping, &
209 force_bounds_in_subcell=force_bounds_in_subcell, &
210 answers_2018=cs%answers_2018)
212 call get_param(param_file, mdl,
"REMAP_AFTER_INITIALIZATION", cs%remap_after_initialization, &
213 "If true, applies regridding and remapping immediately after "//&
214 "initialization so that the state is ALE consistent. This is a "//&
215 "legacy step and should not be needed if the initialization is "//&
216 "consistent with the coordinate mode.", default=.true.)
218 call get_param(param_file, mdl,
"REGRID_TIME_SCALE", cs%regrid_time_scale, &
219 "The time-scale used in blending between the current (old) grid "//&
220 "and the target (new) grid. A short time-scale favors the target "//&
221 "grid (0. or anything less than DT_THERM) has no memory of the old "//&
222 "grid. A very long time-scale makes the model more Lagrangian.", &
223 units=
"s", default=0., scale=us%s_to_T)
224 call get_param(param_file, mdl,
"REGRID_FILTER_SHALLOW_DEPTH", filter_shallow_depth, &
225 "The depth above which no time-filtering is applied. Above this depth "//&
226 "final grid exactly matches the target (new) grid.", &
227 units=
"m", default=0., scale=gv%m_to_H)
228 call get_param(param_file, mdl,
"REGRID_FILTER_DEEP_DEPTH", filter_deep_depth, &
229 "The depth below which full time-filtering is applied with time-scale "//&
230 "REGRID_TIME_SCALE. Between depths REGRID_FILTER_SHALLOW_DEPTH and "//&
231 "REGRID_FILTER_SHALLOW_DEPTH the filter weights adopt a cubic profile.", &
232 units=
"m", default=0., scale=gv%m_to_H)
233 call set_regrid_params(cs%regridCS, depth_of_time_filter_shallow=filter_shallow_depth, &
234 depth_of_time_filter_deep=filter_deep_depth)
235 call get_param(param_file, mdl,
"REGRID_USE_OLD_DIRECTION", local_logical, &
236 "If true, the regridding ntegrates upwards from the bottom for "//&
237 "interface positions, much as the main model does. If false "//&
238 "regridding integrates downward, consistant with the remapping "//&
239 "code.", default=.true., do_not_log=.true.)
240 call set_regrid_params(cs%regridCS, integrate_downward_for_e=.not.local_logical)
245 if (cs%show_call_tree)
call calltree_leave(
"ALE_init()")
246 end subroutine ale_init
249 subroutine ale_register_diags(Time, G, GV, US, diag, CS)
250 type(time_type),
target,
intent(in) :: time
251 type(ocean_grid_type),
intent(in) :: g
254 type(
diag_ctrl),
target,
intent(in) :: diag
255 type(
ale_cs),
pointer :: cs
261 cs%id_u_preale = register_diag_field(
'ocean_model',
'u_preale', diag%axesCuL, time, &
262 'Zonal velocity before remapping',
'm s-1', conversion=us%L_T_to_m_s)
263 cs%id_v_preale = register_diag_field(
'ocean_model',
'v_preale', diag%axesCvL, time, &
264 'Meridional velocity before remapping',
'm s-1', conversion=us%L_T_to_m_s)
265 cs%id_h_preale = register_diag_field(
'ocean_model',
'h_preale', diag%axesTL, time, &
266 'Layer Thickness before remapping', get_thickness_units(gv), &
267 conversion=gv%H_to_MKS, v_extensive=.true.)
268 cs%id_T_preale = register_diag_field(
'ocean_model',
'T_preale', diag%axesTL, time, &
269 'Temperature before remapping',
'degC')
270 cs%id_S_preale = register_diag_field(
'ocean_model',
'S_preale', diag%axesTL, time, &
271 'Salinity before remapping',
'PSU')
272 cs%id_e_preale = register_diag_field(
'ocean_model',
'e_preale', diag%axesTi, time, &
273 'Interface Heights before remapping',
'm', conversion=us%Z_to_m)
275 cs%id_dzRegrid = register_diag_field(
'ocean_model',
'dzRegrid',diag%axesTi,time, &
276 'Change in interface height due to ALE regridding',
'm', &
277 conversion=gv%H_to_m)
278 cs%id_vert_remap_h = register_diag_field(
'ocean_model',
'vert_remap_h', &
279 diag%axestl, time,
'layer thicknesses after ALE regridding and remapping',
'm', &
280 conversion=gv%H_to_m, v_extensive=.true.)
281 cs%id_vert_remap_h_tendency = register_diag_field(
'ocean_model',
'vert_remap_h_tendency',diag%axestl,time, &
282 'Layer thicknesses tendency due to ALE regridding and remapping',
'm', &
283 conversion=gv%H_to_m*us%s_to_T, v_extensive = .true.)
285 end subroutine ale_register_diags
292 subroutine adjustgridforintegrity( CS, G, GV, h )
294 type(ocean_grid_type),
intent(in) :: g
296 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
298 call inflate_vanished_layers_old( cs%regridCS, g, gv, h(:,:,:) )
300 end subroutine adjustgridforintegrity
306 subroutine ale_end(CS)
310 call end_remapping( cs%remapCS )
311 call end_regridding( cs%regridCS )
315 end subroutine ale_end
321 subroutine ale_main( G, GV, US, h, u, v, tv, Reg, CS, OBC, dt, frac_shelf_h)
322 type(ocean_grid_type),
intent(in) :: g
325 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
327 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: u
328 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)),
intent(inout) :: v
331 type(
ale_cs),
pointer :: cs
333 real,
optional,
intent(in) :: dt
334 real,
dimension(:,:),
optional,
pointer :: frac_shelf_h
336 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzregrid
337 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: eta_preale
338 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new
339 integer :: nk, i, j, k, isc, iec, jsc, jec
342 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
345 if (
present(frac_shelf_h))
then 346 if (
associated(frac_shelf_h)) ice_shelf = .true.
349 if (cs%show_call_tree)
call calltree_enter(
"ALE_main(), MOM_ALE.F90")
352 if (cs%id_u_preale > 0)
call post_data(cs%id_u_preale, u, cs%diag)
353 if (cs%id_v_preale > 0)
call post_data(cs%id_v_preale, v, cs%diag)
354 if (cs%id_h_preale > 0)
call post_data(cs%id_h_preale, h, cs%diag)
355 if (cs%id_T_preale > 0)
call post_data(cs%id_T_preale, tv%T, cs%diag)
356 if (cs%id_S_preale > 0)
call post_data(cs%id_S_preale, tv%S, cs%diag)
357 if (cs%id_e_preale > 0)
then 358 call find_eta(h, tv, g, gv, us, eta_preale)
359 call post_data(cs%id_e_preale, eta_preale, cs%diag)
362 if (
present(dt))
then 363 call ale_update_regrid_weights( dt, cs )
365 dzregrid(:,:,:) = 0.0
370 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, frac_shelf_h)
372 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid)
375 call check_grid( g, gv, h, 0. )
377 if (cs%show_call_tree)
call calltree_waypoint(
"new grid generated (ALE_main)")
381 if (
present(dt))
then 382 call diag_update_remap_grids(cs%diag)
385 call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, obc, -dzregrid, &
386 u, v, cs%show_call_tree, dt )
388 if (cs%show_call_tree)
call calltree_waypoint(
"state remapped (ALE_main)")
393 do k = 1,nk ;
do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
394 h(i,j,k) = h_new(i,j,k)
395 enddo ;
enddo ;
enddo 397 if (cs%show_call_tree)
call calltree_leave(
"ALE_main()")
399 if (cs%id_dzRegrid>0 .and.
present(dt))
call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
402 end subroutine ale_main
408 subroutine ale_main_offline( G, GV, h, tv, Reg, CS, OBC, dt)
409 type(ocean_grid_type),
intent(in) :: g
411 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
415 type(
ale_cs),
pointer :: cs
417 real,
optional,
intent(in) :: dt
419 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzregrid
420 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new
421 integer :: nk, i, j, k, isc, iec, jsc, jec
423 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
425 if (cs%show_call_tree)
call calltree_enter(
"ALE_main_offline(), MOM_ALE.F90")
427 if (
present(dt))
then 428 call ale_update_regrid_weights( dt, cs )
430 dzregrid(:,:,:) = 0.0
434 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid )
436 call check_grid( g, gv, h, 0. )
438 if (cs%show_call_tree)
call calltree_waypoint(
"new grid generated (ALE_main)")
442 call remap_all_state_vars(cs%remapCS, cs, g, gv, h, h_new, reg, obc, &
443 debug=cs%show_call_tree, dt=dt )
445 if (cs%show_call_tree)
call calltree_waypoint(
"state remapped (ALE_main)")
450 do k = 1,nk ;
do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
451 h(i,j,k) = h_new(i,j,k)
452 enddo ;
enddo ;
enddo 454 if (cs%show_call_tree)
call calltree_leave(
"ALE_main()")
455 if (cs%id_dzRegrid>0 .and.
present(dt))
call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
457 end subroutine ale_main_offline
462 subroutine ale_offline_inputs(CS, G, GV, h, tv, Reg, uhtr, vhtr, Kd, debug, OBC)
464 type(ocean_grid_type),
intent(in ) :: g
466 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
469 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: uhtr
470 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)),
intent(inout) :: vhtr
471 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1),
intent(inout) :: kd
472 logical,
intent(in ) :: debug
475 integer :: nk, i, j, k, isc, iec, jsc, jec
476 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new
477 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzregrid
478 real,
dimension(SZK_(GV)) :: h_src
479 real,
dimension(SZK_(GV)) :: h_dest, uh_dest
480 real,
dimension(SZK_(GV)) :: temp_vec
482 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
483 dzregrid(:,:,:) = 0.0
486 if (debug)
call mom_tracer_chkinv(
"Before ALE_offline_inputs", g, h, reg%Tr, reg%ntr)
491 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, conv_adjust = .false. )
492 call check_grid( g, gv, h_new, 0. )
493 if (cs%show_call_tree)
call calltree_waypoint(
"new grid generated (ALE_offline_inputs)")
496 call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, obc, debug=cs%show_call_tree )
497 if (cs%show_call_tree)
call calltree_waypoint(
"state remapped (ALE_inputs)")
500 do j=jsc,jec ;
do i=g%iscB,g%iecB
501 if (g%mask2dCu(i,j)>0.)
then 502 h_src(:) = 0.5 * (h(i,j,:) + h(i+1,j,:))
503 h_dest(:) = 0.5 * (h_new(i,j,:) + h_new(i+1,j,:))
504 call reintegrate_column(nk, h_src, uhtr(i,j,:), nk, h_dest, 0., temp_vec)
505 uhtr(i,j,:) = temp_vec
508 do j=g%jscB,g%jecB ;
do i=isc,iec
509 if (g%mask2dCv(i,j)>0.)
then 510 h_src(:) = 0.5 * (h(i,j,:) + h(i,j+1,:))
511 h_dest(:) = 0.5 * (h_new(i,j,:) + h_new(i,j+1,:))
512 call reintegrate_column(nk, h_src, vhtr(i,j,:), nk, h_dest, 0., temp_vec)
513 vhtr(i,j,:) = temp_vec
517 do j = jsc,jec ;
do i=isc,iec
518 if (g%mask2dT(i,j)>0.)
then 519 if (check_column_integrals(nk, h_src, nk, h_dest))
then 520 call mom_error(fatal,
"ALE_offline_inputs: Kd interpolation columns do not match")
522 call interpolate_column(nk, h(i,j,:), kd(i,j,:), nk, h_new(i,j,:), 0., kd(i,j,:))
526 call ale_remap_scalar(cs%remapCS, g, gv, nk, h, tv%T, h_new, tv%T, answers_2018=cs%answers_2018)
527 call ale_remap_scalar(cs%remapCS, g, gv, nk, h, tv%S, h_new, tv%S, answers_2018=cs%answers_2018)
529 if (debug)
call mom_tracer_chkinv(
"After ALE_offline_inputs", g, h_new, reg%Tr, reg%ntr)
532 do k = 1,nk ;
do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
533 h(i,j,k) = h_new(i,j,k)
534 enddo ;
enddo ;
enddo 536 if (cs%show_call_tree)
call calltree_leave(
"ALE_offline_inputs()")
537 end subroutine ale_offline_inputs
543 subroutine ale_offline_tracer_final( G, GV, h, tv, h_target, Reg, CS, OBC)
544 type(ocean_grid_type),
intent(in) :: g
546 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
549 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h_target
552 type(
ale_cs),
pointer :: cs
556 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzregrid
557 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new
558 integer :: nk, i, j, k, isc, iec, jsc, jec
560 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
562 if (cs%show_call_tree)
call calltree_enter(
"ALE_offline_tracer_final(), MOM_ALE.F90")
564 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h_target, tv, h_new, dzregrid )
565 call check_grid( g, gv, h_target, 0. )
568 if (cs%show_call_tree)
call calltree_waypoint(
"Source and target grids checked (ALE_offline_tracer_final)")
572 call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, obc, debug=cs%show_call_tree )
574 if (cs%show_call_tree)
call calltree_waypoint(
"state remapped (ALE_offline_tracer_final)")
580 do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
581 h(i,j,k) = h_new(i,j,k)
584 if (cs%show_call_tree)
call calltree_leave(
"ALE_offline_tracer_final()")
585 end subroutine ale_offline_tracer_final
588 subroutine check_grid( G, GV, h, threshold )
589 type(ocean_grid_type),
intent(in) :: G
590 type(verticalGrid_type),
intent(in) :: GV
591 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
593 real,
intent(in) :: threshold
598 do j = g%jsc,g%jec ;
do i = g%isc,g%iec
599 if (g%mask2dT(i,j)>0.)
then 600 if (minval(h(i,j,:)) < threshold)
then 601 write(0,*)
'check_grid: i,j=',i,j,
'h(i,j,:)=',h(i,j,:)
602 if (threshold <= 0.)
then 603 call mom_error(fatal,
"MOM_ALE, check_grid: negative thickness encountered.")
605 call mom_error(fatal,
"MOM_ALE, check_grid: too tiny thickness encountered.")
612 end subroutine check_grid
615 subroutine ale_build_grid( G, GV, regridCS, remapCS, h, tv, debug, frac_shelf_h )
616 type(ocean_grid_type),
intent(in) :: g
621 real,
dimension(SZI_(G),SZJ_(G), SZK_(GV)),
intent(inout) :: h
623 logical,
optional,
intent(in) :: debug
624 real,
dimension(:,:),
optional,
pointer :: frac_shelf_h
626 integer :: nk, i, j, k
627 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzregrid
628 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new
629 logical :: show_call_tree, use_ice_shelf
631 show_call_tree = .false.
632 if (
present(debug)) show_call_tree = debug
633 if (show_call_tree)
call calltree_enter(
"ALE_build_grid(), MOM_ALE.F90")
634 use_ice_shelf = .false.
635 if (
present(frac_shelf_h))
then 636 if (
associated(frac_shelf_h)) use_ice_shelf = .true.
641 if (use_ice_shelf)
then 642 call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid, frac_shelf_h )
644 call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid )
650 do j = g%jsc,g%jec ;
do i = g%isc,g%iec
651 if (g%mask2dT(i,j)>0.) h(i,j,:) = h_new(i,j,:)
654 if (show_call_tree)
call calltree_leave(
"ALE_build_grid()")
655 end subroutine ale_build_grid
659 subroutine ale_regrid_accelerated(CS, G, GV, h, tv, n, u, v, OBC, Reg, dt, dzRegrid, initial)
661 type(ocean_grid_type),
intent(inout) :: g
663 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
666 integer,
intent(in) :: n
667 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
669 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
673 optional,
pointer :: reg
674 real,
optional,
intent(in) :: dt
675 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), &
676 optional,
intent(inout) :: dzregrid
677 logical,
optional,
intent(in) :: initial
681 integer :: i, j, k, nz
683 type(group_pass_type) :: pass_t_s_h
684 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_loc, h_orig
685 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
target :: t, s
688 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzinterface, dzinttotal
693 dzinttotal(:,:,:) = 0.
701 t(:,:,:) = tv%T(:,:,:)
702 s(:,:,:) = tv%S(:,:,:)
707 h_loc(:,:,:) = h(:,:,:)
708 h_orig(:,:,:) = h(:,:,:)
712 call ale_update_regrid_weights(dt, cs)
715 call do_group_pass(pass_t_s_h, g%domain)
718 call regridding_main(cs%remapCS, cs%regridCS, g, gv, h_loc, tv_local, h, dzinterface)
719 dzinttotal(:,:,:) = dzinttotal(:,:,:) + dzinterface(:,:,:)
722 do j = g%jsc-1,g%jec+1 ;
do i = g%isc-1,g%iec+1
723 call remapping_core_h(cs%remapCS, nz, h_orig(i,j,:), tv%S(i,j,:), nz, h(i,j,:), tv_local%S(i,j,:))
724 call remapping_core_h(cs%remapCS, nz, h_orig(i,j,:), tv%T(i,j,:), nz, h(i,j,:), tv_local%T(i,j,:))
728 h_loc(:,:,:) = h(:,:,:)
732 call remap_all_state_vars(cs%remapCS, cs, g, gv, h_orig, h, reg, obc, dzinttotal, u, v)
735 if (
present(dzregrid)) dzregrid(:,:,:) = dzinttotal(:,:,:)
736 end subroutine ale_regrid_accelerated
744 subroutine remap_all_state_vars(CS_remapping, CS_ALE, G, GV, h_old, h_new, Reg, OBC, &
745 dxInterface, u, v, debug, dt)
746 type(remapping_CS),
intent(in) :: CS_remapping
747 type(ALE_CS),
intent(in) :: CS_ALE
748 type(ocean_grid_type),
intent(in) :: G
749 type(verticalGrid_type),
intent(in) :: GV
750 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_old
752 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_new
754 type(tracer_registry_type),
pointer :: Reg
755 type(ocean_OBC_type),
pointer :: OBC
756 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), &
757 optional,
intent(in) :: dxInterface
759 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
760 optional,
intent(inout) :: u
761 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
762 optional,
intent(inout) :: v
763 logical,
optional,
intent(in) :: debug
764 real,
optional,
intent(in) :: dt
766 integer :: i, j, k, m
768 real,
dimension(GV%ke+1) :: dx
769 real,
dimension(GV%ke) :: h1, u_column
770 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: work_conc
771 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: work_cont
772 real,
dimension(SZI_(G), SZJ_(G)) :: work_2d
775 real,
dimension(GV%ke) :: h2
776 real :: h_neglect, h_neglect_edge
777 logical :: show_call_tree
778 type(tracer_type),
pointer :: Tr => null()
780 show_call_tree = .false.
781 if (
present(debug)) show_call_tree = debug
782 if (show_call_tree)
call calltree_enter(
"remap_all_state_vars(), MOM_ALE.F90")
786 if ( .not.
present(dxinterface) .and. (cs_ale%remap_uv_using_old_alg .and. (
present(u) .or.
present(v))) )
then 787 call mom_error(fatal,
"remap_all_state_vars: dxInterface must be present if using old algorithm "// &
788 "and u/v are to be remapped")
791 if (.not.cs_ale%answers_2018)
then 792 h_neglect = gv%H_subroundoff ; h_neglect_edge = gv%H_subroundoff
793 elseif (gv%Boussinesq)
then 794 h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
796 h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
802 ntr = 0 ;
if (
associated(reg)) ntr = reg%ntr
804 if (
present(dt))
then 806 work_conc(:,:,:) = 0.0
807 work_cont(:,:,:) = 0.0
812 if (show_call_tree)
call calltree_waypoint(
"remapping tracers (remap_all_state_vars)")
816 do j = g%jsc,g%jec ;
do i = g%isc,g%iec ;
if (g%mask2dT(i,j)>0.)
then 820 call remapping_core_h(cs_remapping, nz, h1, tr%t(i,j,:), nz, h2, &
821 u_column, h_neglect, h_neglect_edge)
824 if (
present(dt))
then 825 if (tr%id_remap_conc > 0)
then 827 work_conc(i,j,k) = (u_column(k) - tr%t(i,j,k)) * idt
830 if (tr%id_remap_cont > 0 .or. tr%id_remap_cont_2d > 0)
then 832 work_cont(i,j,k) = (u_column(k)*h2(k) - tr%t(i,j,k)*h1(k)) * idt
837 tr%t(i,j,:) = u_column(:)
838 endif ;
enddo ;
enddo 841 if (
present(dt))
then 842 if (tr%id_remap_conc > 0)
then 843 call post_data(tr%id_remap_conc, work_conc, cs_ale%diag)
845 if (tr%id_remap_cont > 0)
then 846 call post_data(tr%id_remap_cont, work_cont, cs_ale%diag)
848 if (tr%id_remap_cont_2d > 0)
then 849 do j = g%jsc,g%jec ;
do i = g%isc,g%iec
852 work_2d(i,j) = work_2d(i,j) + work_cont(i,j,k)
855 call post_data(tr%id_remap_cont_2d, work_2d, cs_ale%diag)
862 if (show_call_tree)
call calltree_waypoint(
"tracers remapped (remap_all_state_vars)")
865 if (
present(u) )
then 867 do j = g%jsc,g%jec ;
do i = g%iscB,g%iecB ;
if (g%mask2dCu(i,j)>0.)
then 869 h1(:) = 0.5 * ( h_old(i,j,:) + h_old(i+1,j,:) )
870 if (cs_ale%remap_uv_using_old_alg)
then 871 dx(:) = 0.5 * ( dxinterface(i,j,:) + dxinterface(i+1,j,:) )
873 h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
876 h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i+1,j,:) )
878 if (
associated(obc))
then 879 if (obc%segnum_u(i,j) .ne. 0)
then 880 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 884 h1(:) = h_old(i+1,j,:)
885 h2(:) = h_new(i+1,j,:)
889 call remapping_core_h(cs_remapping, nz, h1, u(i,j,:), nz, h2, &
890 u_column, h_neglect, h_neglect_edge)
891 u(i,j,:) = u_column(:)
892 endif ;
enddo ;
enddo 895 if (show_call_tree)
call calltree_waypoint(
"u remapped (remap_all_state_vars)")
898 if (
present(v) )
then 900 do j = g%jscB,g%jecB ;
do i = g%isc,g%iec ;
if (g%mask2dCv(i,j)>0.)
then 902 h1(:) = 0.5 * ( h_old(i,j,:) + h_old(i,j+1,:) )
903 if (cs_ale%remap_uv_using_old_alg)
then 904 dx(:) = 0.5 * ( dxinterface(i,j,:) + dxinterface(i,j+1,:) )
906 h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
909 h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i,j+1,:) )
911 if (
associated(obc))
then 912 if (obc%segnum_v(i,j) .ne. 0)
then 913 if (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_n)
then 917 h1(:) = h_old(i,j+1,:)
918 h2(:) = h_new(i,j+1,:)
922 call remapping_core_h(cs_remapping, nz, h1, v(i,j,:), nz, h2, &
923 u_column, h_neglect, h_neglect_edge)
924 v(i,j,:) = u_column(:)
925 endif ;
enddo ;
enddo 928 if (cs_ale%id_vert_remap_h > 0)
call post_data(cs_ale%id_vert_remap_h, h_old, cs_ale%diag)
929 if ((cs_ale%id_vert_remap_h_tendency > 0) .and.
present(dt))
then 930 do k = 1, nz ;
do j = g%jsc,g%jec ;
do i = g%isc,g%iec
931 work_cont(i,j,k) = (h_new(i,j,k) - h_old(i,j,k))*idt
932 enddo ;
enddo ;
enddo 933 call post_data(cs_ale%id_vert_remap_h_tendency, work_cont, cs_ale%diag)
935 if (show_call_tree)
call calltree_waypoint(
"v remapped (remap_all_state_vars)")
936 if (show_call_tree)
call calltree_leave(
"remap_all_state_vars()")
938 end subroutine remap_all_state_vars
944 subroutine ale_remap_scalar(CS, G, GV, nk_src, h_src, s_src, h_dst, s_dst, all_cells, old_remap, answers_2018 )
946 type(ocean_grid_type),
intent(in) :: g
948 integer,
intent(in) :: nk_src
949 real,
dimension(SZI_(G),SZJ_(G),nk_src),
intent(in) :: h_src
951 real,
dimension(SZI_(G),SZJ_(G),nk_src),
intent(in) :: s_src
952 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_dst
954 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: s_dst
955 logical,
optional,
intent(in) :: all_cells
958 logical,
optional,
intent(in) :: old_remap
960 logical,
optional,
intent(in) :: answers_2018
965 integer :: i, j, k, n_points
967 real :: h_neglect, h_neglect_edge
968 logical :: ignore_vanished_layers, use_remapping_core_w, use_2018_remap
970 ignore_vanished_layers = .false.
971 if (
present(all_cells)) ignore_vanished_layers = .not. all_cells
972 use_remapping_core_w = .false.
973 if (
present(old_remap)) use_remapping_core_w = old_remap
975 use_2018_remap = .true. ;
if (
present(answers_2018)) use_2018_remap = answers_2018
977 if (.not.use_2018_remap)
then 978 h_neglect = gv%H_subroundoff ; h_neglect_edge = gv%H_subroundoff
979 elseif (gv%Boussinesq)
then 980 h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
982 h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
986 do j = g%jsc,g%jec ;
do i = g%isc,g%iec
987 if (g%mask2dT(i,j) > 0.)
then 988 if (ignore_vanished_layers)
then 991 if (h_src(i,j,k)>0.) n_points = n_points + 1
995 if (use_remapping_core_w)
then 996 call dzfromh1h2( n_points, h_src(i,j,1:n_points), gv%ke, h_dst(i,j,:), dx )
997 call remapping_core_w(cs, n_points, h_src(i,j,1:n_points), s_src(i,j,1:n_points), &
998 gv%ke, dx, s_dst(i,j,:), h_neglect, h_neglect_edge)
1000 call remapping_core_h(cs, n_points, h_src(i,j,1:n_points), s_src(i,j,1:n_points), &
1001 gv%ke, h_dst(i,j,:), s_dst(i,j,:), h_neglect, h_neglect_edge)
1008 end subroutine ale_remap_scalar
1013 subroutine ts_plm_edge_values( CS, S_t, S_b, T_t, T_b, G, GV, tv, h, bdry_extrap )
1014 type(ocean_grid_type),
intent(in) :: g
1016 type(
ale_cs),
intent(inout) :: cs
1017 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1018 intent(inout) :: s_t
1019 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1020 intent(inout) :: s_b
1021 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1022 intent(inout) :: t_t
1023 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1024 intent(inout) :: t_b
1026 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1028 logical,
intent(in) :: bdry_extrap
1031 call ale_plm_edge_values( cs, g, gv, h, tv%S, bdry_extrap, s_t, s_b )
1032 call ale_plm_edge_values( cs, g, gv, h, tv%T, bdry_extrap, t_t, t_b )
1034 end subroutine ts_plm_edge_values
1038 subroutine ale_plm_edge_values( CS, G, GV, h, Q, bdry_extrap, Q_t, Q_b )
1040 type(ocean_grid_type),
intent(in) :: g
1042 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1044 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1046 logical,
intent(in) :: bdry_extrap
1048 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1049 intent(inout) :: q_t
1050 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1051 intent(inout) :: q_b
1058 if (.not.cs%answers_2018)
then 1059 h_neglect = gv%H_subroundoff
1060 elseif (gv%Boussinesq)
then 1061 h_neglect = gv%m_to_H*1.0e-30
1063 h_neglect = gv%kg_m2_to_H*1.0e-30
1067 do j = g%jsc-1,g%jec+1 ;
do i = g%isc-1,g%iec+1
1070 slp(k) = plm_slope_wa(h(i,j,k-1), h(i,j,k), h(i,j,k+1), h_neglect, q(i,j,k-1), q(i,j,k), q(i,j,k+1))
1075 mslp = plm_monotonized_slope(q(i,j,k-1), q(i,j,k), q(i,j,k+1), slp(k-1), slp(k), slp(k+1))
1076 q_t(i,j,k) = q(i,j,k) - 0.5 * mslp
1077 q_b(i,j,k) = q(i,j,k) + 0.5 * mslp
1079 if (bdry_extrap)
then 1080 mslp = - plm_extrapolate_slope(h(i,j,2), h(i,j,1), h_neglect, q(i,j,2), q(i,j,1))
1081 q_t(i,j,1) = q(i,j,1) - 0.5 * mslp
1082 q_b(i,j,1) = q(i,j,1) + 0.5 * mslp
1083 mslp = plm_extrapolate_slope(h(i,j,gv%ke-1), h(i,j,gv%ke), h_neglect, q(i,j,gv%ke-1), q(i,j,gv%ke))
1084 q_t(i,j,gv%ke) = q(i,j,gv%ke) - 0.5 * mslp
1085 q_b(i,j,gv%ke) = q(i,j,gv%ke) + 0.5 * mslp
1087 q_t(i,j,1) = q(i,j,1)
1088 q_b(i,j,1) = q(i,j,1)
1089 q_t(i,j,gv%ke) = q(i,j,gv%ke)
1090 q_b(i,j,gv%ke) = q(i,j,gv%ke)
1095 end subroutine ale_plm_edge_values
1099 subroutine ts_ppm_edge_values( CS, S_t, S_b, T_t, T_b, G, GV, tv, h, bdry_extrap )
1100 type(ocean_grid_type),
intent(in) :: g
1102 type(
ale_cs),
intent(inout) :: cs
1103 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1104 intent(inout) :: s_t
1105 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1106 intent(inout) :: s_b
1107 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1108 intent(inout) :: t_t
1109 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1110 intent(inout) :: t_b
1112 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1114 logical,
intent(in) :: bdry_extrap
1121 real,
dimension(CS%nk,2) :: &
1123 real,
dimension(CS%nk,3) :: &
1125 real :: h_neglect, h_neglect_edge
1127 if (.not.cs%answers_2018)
then 1128 h_neglect = gv%H_subroundoff ; h_neglect_edge = gv%H_subroundoff
1129 elseif (gv%Boussinesq)
then 1130 h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
1132 h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
1137 do j = g%jsc-1,g%jec+1 ;
do i = g%isc-1,g%iec+1
1141 tmp(:) = tv%S(i,j,:)
1145 ppol_coefs(:,:) = 0.0
1146 call edge_values_implicit_h4( gv%ke, htmp, tmp, ppol_e, h_neglect=h_neglect_edge, &
1147 answers_2018=cs%answers_2018 )
1148 call ppm_reconstruction( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect, &
1149 answers_2018=cs%answers_2018 )
1151 call ppm_boundary_extrapolation( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1154 s_t(i,j,k) = ppol_e(k,1)
1155 s_b(i,j,k) = ppol_e(k,2)
1160 ppol_coefs(:,:) = 0.0
1161 tmp(:) = tv%T(i,j,:)
1162 if (cs%answers_2018)
then 1163 call edge_values_implicit_h4( gv%ke, htmp, tmp, ppol_e, h_neglect=1.0e-10*gv%m_to_H, &
1164 answers_2018=cs%answers_2018 )
1166 call edge_values_implicit_h4( gv%ke, htmp, tmp, ppol_e, h_neglect=gv%H_subroundoff, &
1167 answers_2018=cs%answers_2018 )
1169 call ppm_reconstruction( gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect, &
1170 answers_2018=cs%answers_2018 )
1172 call ppm_boundary_extrapolation(gv%ke, htmp, tmp, ppol_e, ppol_coefs, h_neglect )
1175 t_t(i,j,k) = ppol_e(k,1)
1176 t_b(i,j,k) = ppol_e(k,2)
1181 end subroutine ts_ppm_edge_values
1185 subroutine ale_initregridding(GV, US, max_depth, param_file, mdl, regridCS)
1188 real,
intent(in) :: max_depth
1190 character(len=*),
intent(in) :: mdl
1193 character(len=30) :: coord_mode
1195 call get_param(param_file, mdl,
"REGRIDDING_COORDINATE_MODE", coord_mode, &
1196 "Coordinate mode for vertical regridding. "//&
1197 "Choose among the following possibilities: "//&
1198 trim(regriddingcoordinatemodedoc), &
1199 default=default_coordinate_mode, fail_if_missing=.true.)
1201 call initialize_regridding(regridcs, gv, us, max_depth, param_file, mdl, coord_mode,
'',
'')
1203 end subroutine ale_initregridding
1206 function ale_getcoordinate( CS )
1209 real,
dimension(CS%nk+1) :: ale_getcoordinate
1210 ale_getcoordinate(:) = getcoordinateinterfaces( cs%regridCS, undo_scaling=.true. )
1212 end function ale_getcoordinate
1216 function ale_getcoordinateunits( CS )
1219 character(len=20) :: ale_getcoordinateunits
1221 ale_getcoordinateunits = getcoordinateunits( cs%regridCS )
1223 end function ale_getcoordinateunits
1227 logical function ale_remap_init_conds( CS )
1230 ale_remap_init_conds = .false.
1231 if (
associated(cs)) ale_remap_init_conds = cs%remap_after_initialization
1232 end function ale_remap_init_conds
1235 subroutine ale_update_regrid_weights( dt, CS )
1236 real,
intent(in) :: dt
1237 type(
ale_cs),
pointer :: cs
1241 if (
associated(cs))
then 1243 if (cs%regrid_time_scale > 0.0)
then 1244 w = cs%regrid_time_scale / (cs%regrid_time_scale + dt)
1246 call set_regrid_params(cs%regridCS, old_grid_weight=w)
1249 end subroutine ale_update_regrid_weights
1254 subroutine ale_updateverticalgridtype(CS, GV)
1261 gv%sInterface(1:nk+1) = getcoordinateinterfaces( cs%regridCS, undo_scaling=.true. )
1262 gv%sLayer(1:nk) = 0.5*( gv%sInterface(1:nk) + gv%sInterface(2:nk+1) )
1263 gv%zAxisUnits = getcoordinateunits( cs%regridCS )
1264 gv%zAxisLongName = getcoordinateshortname( cs%regridCS )
1268 end subroutine ale_updateverticalgridtype
1274 subroutine ale_writecoordinatefile( CS, GV, directory )
1277 character(len=*),
intent(in) :: directory
1279 character(len=240) :: filepath
1281 type(fieldtype) :: fields(2)
1283 real :: ds(gv%ke), dsi(gv%ke+1)
1285 filepath = trim(directory) // trim(
"Vertical_coordinate")
1286 ds(:) = getcoordinateresolution( cs%regridCS, undo_scaling=.true. )
1288 dsi(2:gv%ke) = 0.5*( ds(1:gv%ke-1) + ds(2:gv%ke) )
1289 dsi(gv%ke+1) = 0.5*ds(gv%ke)
1291 vars(1) = var_desc(
'ds', getcoordinateunits( cs%regridCS ), &
1292 'Layer Coordinate Thickness',
'1',
'L',
'1')
1293 vars(2) = var_desc(
'ds_interface', getcoordinateunits( cs%regridCS ), &
1294 'Layer Center Coordinate Separation',
'1',
'i',
'1')
1296 call create_file(unit, trim(filepath), vars, 2, fields, single_file, gv=gv)
1297 call write_field(unit, fields(1), ds)
1298 call write_field(unit, fields(2), dsi)
1299 call close_file(unit)
1301 end subroutine ale_writecoordinatefile
1305 subroutine ale_initthicknesstocoord( CS, G, GV, h )
1307 type(ocean_grid_type),
intent(in) :: g
1309 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(out) :: h
1314 do j = g%jsd,g%jed ;
do i = g%isd,g%ied
1315 h(i,j,:) = gv%Z_to_H * getstaticthickness( cs%regridCS, 0., g%bathyT(i,j) )
1318 end subroutine ale_initthicknesstocoord
Returns true if the coordinate is dependent on the state density, returns false otherwise.
Calculates the heights of sruface or all interfaces from layer thicknesses.
Returns a string with the coordinate units associated with the coordinate mode.
Provides kernels for single-column interpolation, re-integration (re-mapping of integrated quantities...
This module contains the main regridding routines.
Functions for calculating interface heights, including free surface height.
Calculates density of sea water from T, S and P.
A structure that can be parsed to read and document run-time parameters.
Generates vertical grids as part of the ALE algorithm.
Provides column-wise vertical remapping functions.
Provides functions used with the Piecewise-Parabolic-Method in the vertical ALE algorithm.
This module contains I/O framework code.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
Container for remapping parameters.
Piecewise linear reconstruction functions.
Make a diagnostic available for averaging or output.
Describes various unit conversion factors.
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
Regridding control structure.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Describes the decomposed MOM domain and has routines for communications across PEs.
Type to carry basic tracer information.
Routines for error handling and I/O management.
Provides subroutines for quantities specific to the equation of state.
Type for describing a variable, typically a tracer.
Describes the vertical ocean grid, including unit conversion factors.
Set up a group of halo updates.
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Edge value estimation for high-order resconstruction.
Contains constants for interpreting input parameters that control regridding.
Controls where open boundary conditions are applied.
Handy functions for manipulating strings.
Provides a transparent vertical ocean grid type and supporting routines.
Provides transparent structures with groups of MOM6 variables and supporting routines.
An overloaded interface to read and log the values of various types of parameters.
Provides checksumming functions for debugging.