56 implicit none ;
private 57 #include <MOM_memory.h> 64 logical :: boundary_extrapolation_for_pressure
67 logical :: reconstructforpressure = .false.
77 logical :: remap_uv_using_old_alg
81 real :: regrid_time_scale
88 integer :: degree_linear=1
89 integer :: degree_parab=2
91 logical :: remap_after_initialization
93 logical :: show_call_tree
98 integer,
dimension(:),
allocatable :: id_tracer_remap_tendency
99 integer,
dimension(:),
allocatable :: id_htracer_remap_tendency
100 integer,
dimension(:),
allocatable :: id_htracer_remap_tendency_2d
101 logical,
dimension(:),
allocatable :: do_tendency_diag
102 integer :: id_dzregrid = -1
137 subroutine ale_init( param_file, GV, max_depth, CS)
140 real,
intent(in) :: max_depth
141 type(
ale_cs),
pointer :: CS
144 real,
dimension(:),
allocatable :: dz
145 character(len=40) :: mdl =
"MOM_ALE" 146 character(len=80) :: string
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
153 if (
associated(cs))
then 154 call mom_error(warning,
"ALE_init called with an associated "// &
155 "control structure.")
160 cs%show_call_tree = calltree_showquery()
161 if (cs%show_call_tree)
call calltree_enter(
"ALE_init(), MOM_ALE.F90")
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.)
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.", &
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"//&
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.", &
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)
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.)
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)
261 type(time_type),
target,
intent(in) :: Time
262 type(ocean_grid_type),
intent(in) :: G
263 type(
diag_ctrl),
target,
intent(in) :: diag
264 real,
intent(in) :: C_p
266 type(
ale_cs),
pointer :: CS
268 integer :: m, ntr, nsize
270 if (
associated(reg))
then 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
290 'Change in interface height due to ALE regridding',
'meter')
295 if(trim(reg%Tr(m)%name) ==
'T')
then 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),&
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.)
308 trim(reg%Tr(m)%name)//
'h_tendency_vert_remap_2d', diag%axesT1, time, &
309 'Vertical sum of tendency from vertical remapping for heat', &
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),&
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.)
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),&
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.
348 type(ocean_grid_type),
intent(in) :: G
350 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
352 call inflate_vanished_layers_old( cs%regridCS, g, gv, h(:,:,:) )
364 call end_remapping( cs%remapCS )
365 call end_regridding( cs%regridCS )
375 subroutine ale_main( G, GV, h, u, v, tv, Reg, CS, dt, frac_shelf_h)
376 type(ocean_grid_type),
intent(in) :: G
378 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
379 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: u
380 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)),
intent(inout) :: v
383 type(
ale_cs),
pointer :: CS
384 real,
optional,
intent(in) :: dt
385 real,
dimension(:,:),
optional,
pointer :: frac_shelf_h
387 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid
388 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new
389 integer :: nk, i, j, k, isc, iec, jsc, jec
392 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
395 if (
present(frac_shelf_h))
then 396 if (
associated(frac_shelf_h)) ice_shelf = .true.
399 if (cs%show_call_tree)
call calltree_enter(
"ALE_main(), MOM_ALE.F90")
401 if (
present(dt))
then 404 dzregrid(:,:,:) = 0.0
409 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, frac_shelf_h)
411 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid)
421 u, v, cs%show_call_tree, dt )
429 do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
430 h(i,j,k) = h_new(i,j,k)
436 if (cs%id_dzRegrid>0 .and.
present(dt))
call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
446 type(ocean_grid_type),
intent(in) :: G
448 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
451 type(
ale_cs),
pointer :: CS
452 real,
optional,
intent(in) :: dt
454 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid
455 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new
456 integer :: nk, i, j, k, isc, iec, jsc, jec
458 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
460 if (cs%show_call_tree)
call calltree_enter(
"ALE_main_offline(), MOM_ALE.F90")
462 if (
present(dt))
then 465 dzregrid(:,:,:) = 0.0
469 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid )
477 call remap_all_state_vars( cs%remapCS, cs, g, gv, h, h_new, reg, debug=cs%show_call_tree, dt=dt )
485 do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
486 h(i,j,k) = h_new(i,j,k)
491 if (cs%id_dzRegrid>0 .and.
present(dt))
call post_data(cs%id_dzRegrid, dzregrid, cs%diag)
500 type(ocean_grid_type),
intent(in ) :: G
502 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
505 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: uhtr
506 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)),
intent(inout) :: vhtr
507 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1),
intent(inout) :: Kd
508 logical,
intent(in ) :: debug
510 integer :: nk, i, j, k, isc, iec, jsc, jec
511 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new
512 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid
513 real,
dimension(SZK_(GV)) :: h_src
514 real,
dimension(SZK_(GV)) :: h_dest, uh_dest
515 real,
dimension(SZK_(GV)) :: temp_vec
517 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
518 dzregrid(:,:,:) = 0.0
521 if (debug)
call mom_tracer_chkinv(
"Before ALE_offline_inputs", g, h, reg%Tr, reg%ntr)
526 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h, tv, h_new, dzregrid, conv_adjust = .false. )
528 if (cs%show_call_tree)
call calltree_waypoint(
"new grid generated (ALE_offline_inputs)")
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,:))
540 uhtr(i,j,:) = temp_vec
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,:))
548 vhtr(i,j,:) = temp_vec
552 do j = jsc,jec ;
do i=isc,iec
553 if (g%mask2dT(i,j)>0.)
then 555 call mom_error(fatal,
"ALE_offline_inputs: Kd interpolation columns do not match")
557 call interpolate_column(nk, h(i,j,:), kd(i,j,:), nk, h_new(i,j,:), 0., kd(i,j,:))
564 if (debug)
call mom_tracer_chkinv(
"After ALE_offline_inputs", g, h_new, reg%Tr, reg%ntr)
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 571 if (cs%show_call_tree)
call calltree_leave(
"ALE_offline_inputs()")
579 type(ocean_grid_type),
intent(in) :: G
581 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h
584 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: h_target
587 type(
ale_cs),
pointer :: CS
590 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid
591 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new
592 integer :: nk, i, j, k, isc, iec, jsc, jec
594 nk = gv%ke; isc = g%isc; iec = g%iec; jsc = g%jsc; jec = g%jec
596 if (cs%show_call_tree)
call calltree_enter(
"ALE_offline_tracer_final(), MOM_ALE.F90")
598 call regridding_main( cs%remapCS, cs%regridCS, g, gv, h_target, tv, h_new, dzregrid )
602 if (cs%show_call_tree)
call calltree_waypoint(
"Source and target grids checked (ALE_offline_tracer_final)")
608 if (cs%show_call_tree)
call calltree_waypoint(
"state remapped (ALE_offline_tracer_final)")
614 do j = jsc-1,jec+1 ;
do i = isc-1,iec+1
615 h(i,j,k) = h_new(i,j,k)
618 if (cs%show_call_tree)
call calltree_leave(
"ALE_offline_tracer_final()")
623 type(ocean_grid_type),
intent(in) :: G
625 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
626 real,
intent(in) :: threshold
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.")
637 call mom_error(fatal,
"MOM_ALE, check_grid: too tiny thickness encountered.")
647 subroutine ale_build_grid( G, GV, regridCS, remapCS, h, tv, debug, frac_shelf_h )
648 type(ocean_grid_type),
intent(in) :: G
653 real,
dimension(SZI_(G),SZJ_(G), SZK_(GV)),
intent(inout) :: h
654 logical,
optional,
intent(in) :: debug
655 real,
dimension(:,:),
optional,
pointer :: frac_shelf_h
657 integer :: nk, i, j, k
658 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid
659 real,
dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: h_new
660 logical :: show_call_tree, use_ice_shelf
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.
672 if (use_ice_shelf)
then 673 call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid, frac_shelf_h )
675 call regridding_main( remapcs, regridcs, g, gv, h, tv, h_new, dzregrid )
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,:)
692 type(ocean_grid_type),
intent(inout) :: G
694 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_orig
696 integer,
intent(in) :: n
697 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(out) :: h_new
698 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: u
699 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)),
intent(inout) :: v
702 integer :: i, j, k, nz
704 type(group_pass_type) :: pass_T_S_h
705 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h
706 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
target :: T, S
709 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzInterface, dzIntTotal
714 dzinttotal(:,:,:) = 0.
722 t(:,:,:) = tv%T(:,:,:)
723 s(:,:,:) = tv%S(:,:,:)
728 h(:,:,:) = h_orig(:,:,:)
734 call regridding_main(cs%remapCS, cs%regridCS, g, gv, h, tv_local, h_new, dzinterface)
735 dzinttotal(:,:,:) = dzinttotal(:,:,:) + dzinterface(:,:,:)
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,:))
746 h(:,:,:) = h_new(:,:,:)
750 tv%S(:,:,:) = s(:,:,:)
751 tv%T(:,:,:) = t(:,:,:)
763 subroutine remap_all_state_vars(CS_remapping, CS_ALE, G, GV, h_old, h_new, Reg, dxInterface, u, v, debug, dt)
765 type(
ale_cs),
intent(in) :: CS_ALE
766 type(ocean_grid_type),
intent(in) :: G
768 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_old
769 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_new
771 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)+1),
optional,
intent(in) :: dxInterface
772 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)),
optional,
intent(inout) :: u
773 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)),
optional,
intent(inout) :: v
774 logical,
optional,
intent(in) :: debug
775 real,
optional,
intent(in) :: dt
777 integer :: i, j, k, m
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
785 real,
dimension(GV%ke) :: h2
786 logical :: show_call_tree
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")
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"// &
802 if (
associated(reg))
then 809 work_conc(:,:,:) = 0.0
810 work_cont(:,:,:) = 0.0
820 if (show_call_tree)
call calltree_waypoint(
"remapping tracers (remap_all_state_vars)")
827 if (g%mask2dT(i,j)>0.)
then 832 call remapping_core_h(cs_remapping, nz, h1, reg%Tr(m)%t(i,j,:), nz, h2, u_column)
838 if(cs_ale%do_tendency_diag(m))
then 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
847 reg%Tr(m)%t(i,j,:) = u_column(:)
861 if(cs_ale%do_tendency_diag(m))
then 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)
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 872 work_cont(i,j,k) = work_cont(i,j,k) * cs_ale%C_p
876 elseif(trim(reg%Tr(m)%name) ==
'S')
then 880 work_cont(i,j,k) = work_cont(i,j,k) * ppt2mks
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)
890 if (cs_ale%id_Htracer_remap_tendency_2d(m) > 0)
then 895 work_2d(i,j) = work_2d(i,j) + work_cont(i,j,k)
899 call post_data(cs_ale%id_Htracer_remap_tendency_2d(m), work_2d, cs_ale%diag)
909 if (show_call_tree)
call calltree_waypoint(
"tracers remapped (remap_all_state_vars)")
912 if (
present(u) )
then 916 if (g%mask2dCu(i,j)>0.)
then 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,:) )
922 h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
925 h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i+1,j,:) )
927 call remapping_core_h(cs_remapping, nz, h1, u(i,j,:), nz, h2, u_column)
928 u(i,j,:) = u_column(:)
937 if (
present(v) )
then 941 if (g%mask2dCv(i,j)>0.)
then 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,:) )
947 h2(k) = max( 0., h1(k) + ( dx(k+1) - dx(k) ) )
950 h2(:) = 0.5 * ( h_new(i,j,:) + h_new(i,j+1,:) )
952 call remapping_core_h(cs_remapping, nz, h1, v(i,j,:), nz, h2, u_column)
953 v(i,j,:) = u_column(:)
969 subroutine ale_remap_scalar(CS, G, GV, nk_src, h_src, s_src, h_dst, s_dst, all_cells, old_remap )
971 type(ocean_grid_type),
intent(in) :: G
973 integer,
intent(in) :: nk_src
974 real,
dimension(SZI_(G),SZJ_(G),nk_src),
intent(in) :: h_src
975 real,
dimension(SZI_(G),SZJ_(G),nk_src),
intent(in) :: s_src
976 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_dst
977 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: s_dst
978 logical,
optional,
intent(in) :: all_cells
981 logical,
optional,
intent(in) :: old_remap
984 integer :: i, j, k, n_points
986 logical :: ignore_vanished_layers, use_remapping_core_w
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
1000 if (g%mask2dT(i,j)>0.)
then 1001 if (ignore_vanished_layers)
then 1004 if (h_src(i,j,k)>0.) n_points = n_points + 1
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,:))
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,:))
1030 type(ocean_grid_type),
intent(in) :: G
1032 type(
ale_cs),
intent(inout) :: CS
1033 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: S_t
1034 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: S_b
1035 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: T_t
1036 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: T_b
1038 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
1044 real,
dimension(CS%nk,2) :: ppoly_linear_E
1045 real,
dimension(CS%nk,CS%degree_linear+1) :: ppoly_linear_coefficients
1053 do j = g%jsc-1,g%jec+1
1054 do i = g%isc-1,g%iec+1
1056 htmp(:) = h(i,j,:)*gv%H_to_m
1057 tmp(:) = tv%S(i,j,:)
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 &
1066 s_t(i,j,k) = ppoly_linear_e(k,1)
1067 s_b(i,j,k) = ppoly_linear_e(k,2)
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 &
1079 t_t(i,j,k) = ppoly_linear_e(k,1)
1080 t_b(i,j,k) = ppoly_linear_e(k,2)
1095 type(ocean_grid_type),
intent(in) :: G
1097 type(
ale_cs),
intent(inout) :: CS
1098 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: S_t
1099 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: S_b
1100 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: T_t
1101 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(inout) :: T_b
1103 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h
1109 real,
dimension(CS%nk,2) :: &
1111 real,
dimension(CS%nk,CS%degree_parab+1) :: &
1112 ppoly_parab_coefficients
1121 do j = g%jsc-1,g%jec+1
1122 do i = g%isc-1,g%iec+1
1125 htmp(:) = h(i,j,:) * gv%H_to_m
1126 tmp(:) = tv%S(i,j,:)
1130 ppoly_parab_coefficients = 0.0
1133 if (cs%boundary_extrapolation_for_pressure)
call &
1137 s_t(i,j,k) = ppoly_parab_e(k,1)
1138 s_b(i,j,k) = ppoly_parab_e(k,2)
1143 ppoly_parab_coefficients = 0.0
1144 tmp(:) = tv%T(i,j,:)
1147 if (cs%boundary_extrapolation_for_pressure)
call &
1151 t_t(i,j,k) = ppoly_parab_e(k,1)
1152 t_b(i,j,k) = ppoly_parab_e(k,2)
1165 if (
associated(cs))
then 1178 if (
associated(cs))
then 1189 real,
intent(in) :: max_depth
1191 character(len=*),
intent(in) :: mdl
1194 character(len=30) :: coord_mode
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.)
1202 call initialize_regridding(regridcs, gv, max_depth, param_file, mdl, coord_mode,
'',
'')
1210 real,
dimension(CS%nk+1) :: ALE_getCoordinate
1211 ale_getcoordinate(:) = getcoordinateinterfaces( cs%regridCS )
1220 character(len=20) :: ALE_getCoordinateUnits
1222 ale_getcoordinateunits = getcoordinateunits( cs%regridCS )
1237 real,
intent(in) :: dt
1238 type(
ale_cs),
pointer :: CS
1242 if (
associated(cs))
then 1244 if (cs%regrid_time_scale > 0.0)
then 1245 w = cs%regrid_time_scale / (cs%regrid_time_scale + dt)
1247 call set_regrid_params(cs%regridCS, old_grid_weight=w)
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 )
1278 character(len=*),
intent(in) :: directory
1280 character(len=240) :: filepath
1282 type(fieldtype) :: fields(2)
1284 real :: ds(gv%ke), dsi(gv%ke+1)
1286 filepath = trim(directory) // trim(
"Vertical_coordinate")
1287 ds(:) = getcoordinateresolution( cs%regridCS )
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)
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')
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)
1308 type(ocean_grid_type),
intent(in) :: G
1310 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(out) :: h
1315 do j = g%jsd,g%jed ;
do i = g%isd,g%ied
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...
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...
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...
This module contains the main regridding routines. Regridding comprises two steps: (1) Interpolation ...
character(len=20) function, public getcoordinateunits(CS)
integer, parameter pressure_reconstruction_plm
character(len=3), public remappingdefaultscheme
Default remapping method.
logical function, public usepressurereconstruction(CS)
pressure reconstruction logical
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.
Calculates density of sea water from T, S and P.
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.
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.
subroutine, public ale_register_diags(Time, G, diag, C_p, Reg, CS)
Initialize diagnostics for the ALE module.
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.
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...
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...
subroutine, public ale_end(CS)
End of regridding (memory deallocation). This routine is typically called (from MOM_end in file MOM...
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...
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.
logical function, public ale_remap_init_conds(CS)
Returns true if initial conditions should be regridded and remapped.
character(len=len(input_string)) function, public uppercase(input_string)
character(len=20) function, public ale_getcoordinateunits(CS)
Query the target coordinate units.
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.
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...
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
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.
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.
subroutine, public adjustgridforintegrity(CS, G, GV, h)
Crudely adjust (initial) grid for integrity. This routine is typically called (from initialize_MOM in...
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.
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.
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...
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...
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...
subroutine, public initialize_remapping(CS, remapping_scheme, boundary_extrapolation, check_reconstruction, check_remapping, force_bounds_in_subcell)
Constructor for remapping control structure.
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...
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...
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...
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.