This subroutine applies damping to the layers thicknesses, temp, salt and a variety of tracers for every column where there is damping.
788 type(ocean_grid_type),
intent(inout) :: g
789 type(verticalgrid_type),
intent(in) :: gv
790 type(unit_scale_type),
intent(in) :: us
791 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
793 real,
intent(in) :: dt
794 type(ale_sponge_cs),
pointer :: cs
796 type(time_type),
optional,
intent(in) :: time
801 real,
allocatable,
dimension(:) :: tmp_val2
802 real,
dimension(SZK_(G)) :: tmp_val1
803 real :: hu(szib_(g), szj_(g), szk_(g))
804 real :: hv(szi_(g), szjb_(g), szk_(g))
805 real,
allocatable,
dimension(:,:,:) :: sp_val
806 real,
allocatable,
dimension(:,:,:) :: mask_z
807 real,
dimension(:),
allocatable :: hsrc
809 real,
dimension(:),
allocatable :: tmpt1d
810 integer :: c, m, nkmb, i, j, k, is, ie, js, je, nz, nz_data
811 integer :: col, total_sponge_cols
812 real,
allocatable,
dimension(:),
target :: z_in, z_edges_in
813 real :: missing_value
814 real :: h_neglect, h_neglect_edge
815 real :: ztopofcell, zbottomofcell
818 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
819 if (.not.
associated(cs))
return 821 if (.not.cs%remap_answers_2018)
then 822 h_neglect = gv%H_subroundoff ; h_neglect_edge = gv%H_subroundoff
823 elseif (gv%Boussinesq)
then 824 h_neglect = gv%m_to_H*1.0e-30 ; h_neglect_edge = gv%m_to_H*1.0e-10
826 h_neglect = gv%kg_m2_to_H*1.0e-30 ; h_neglect_edge = gv%kg_m2_to_H*1.0e-10
829 if (cs%time_varying_sponges)
then 830 if (.not.
present(time)) &
831 call mom_error(fatal,
"apply_ALE_sponge: No time information provided")
833 nz_data = cs%Ref_val(m)%nz_data
834 allocate(sp_val(g%isd:g%ied,g%jsd:g%jed,1:nz_data))
835 allocate(mask_z(g%isd:g%ied,g%jsd:g%jed,1:nz_data))
838 call horiz_interp_and_extrap_tracer(cs%Ref_val(m)%id, time, 1.0, g, sp_val, mask_z, z_in, &
839 z_edges_in, missing_value, .true., .false., .false., &
840 spongeongrid=cs%SpongeDataOngrid, m_to_z=us%m_to_Z, &
841 answers_2018=cs%hor_regrid_answers_2018)
842 allocate( hsrc(nz_data) )
843 allocate( tmpt1d(nz_data) )
845 i = cs%col_i(c) ; j = cs%col_j(c)
846 cs%Ref_val(m)%p(1:nz_data,c) = sp_val(i,j,1:nz_data)
848 ztopofcell = 0. ; zbottomofcell = 0. ; npoints = 0; hsrc(:) = 0.0; tmpt1d(:) = -99.9
850 if (mask_z(cs%col_i(c),cs%col_j(c),k) == 1.0)
then 851 zbottomofcell = -min( z_edges_in(k+1), g%bathyT(cs%col_i(c),cs%col_j(c)) )
852 tmpt1d(k) = sp_val(cs%col_i(c),cs%col_j(c),k)
854 zbottomofcell = -g%bathyT(cs%col_i(c),cs%col_j(c))
855 tmpt1d(k) = tmpt1d(k-1)
859 hsrc(k) = ztopofcell - zbottomofcell
860 if (hsrc(k)>0.) npoints = npoints + 1
861 ztopofcell = zbottomofcell
864 hsrc(nz_data) = hsrc(nz_data) + ( ztopofcell + g%bathyT(cs%col_i(c),cs%col_j(c)) )
865 cs%Ref_val(m)%h(1:nz_data,c) = gv%Z_to_H*hsrc(1:nz_data)
866 cs%Ref_val(m)%p(1:nz_data,c) = tmpt1d(1:nz_data)
869 if (cs%Ref_val(m)%h(k,c) <= 0.001*gv%m_to_H) &
872 cs%Ref_val(m)%p(k,c) = cs%Ref_val(m)%p(k-1,c)
875 deallocate(sp_val, mask_z, hsrc, tmpt1d)
881 allocate(tmp_val2(nz_data))
886 i = cs%col_i(c) ; j = cs%col_j(c)
887 damp = dt * cs%Iresttime_col(c)
888 i1pdamp = 1.0 / (1.0 + damp)
889 tmp_val2(1:nz_data) = cs%Ref_val(m)%p(1:nz_data,c)
890 if (cs%time_varying_sponges)
then 891 call remapping_core_h(cs%remap_cs, nz_data, cs%Ref_val(m)%h(1:nz_data,c), tmp_val2, &
892 cs%nz, h(i,j,:), tmp_val1, h_neglect, h_neglect_edge)
894 call remapping_core_h(cs%remap_cs,nz_data, cs%Ref_h%p(1:nz_data,c), tmp_val2, &
895 cs%nz, h(i,j,:), tmp_val1, h_neglect, h_neglect_edge)
898 cs%var(m)%p(i,j,1:cs%nz) = i1pdamp * (cs%var(m)%p(i,j,1:cs%nz) + tmp_val1 * damp)
909 if (cs%sponge_uv)
then 911 do j=cs%jsc,cs%jec;
do i=cs%iscB,cs%iecB;
do k=1,nz
912 hu(i,j,k) = 0.5 * (h(i,j,k) + h(i+1,j,k))
913 enddo ;
enddo ;
enddo 914 if (cs%time_varying_sponges)
then 915 if (.not.
present(time)) &
916 call mom_error(fatal,
"apply_ALE_sponge: No time information provided")
918 nz_data = cs%Ref_val_u%nz_data
919 allocate(sp_val(g%isdB:g%iedB,g%jsd:g%jed,1:nz_data))
920 allocate(mask_z(g%isdB:g%iedB,g%jsd:g%jed,1:nz_data))
922 call horiz_interp_and_extrap_tracer(cs%Ref_val_u%id, time, 1.0, g, sp_val, mask_z, z_in, &
923 z_edges_in, missing_value, .true., .false., .false., &
924 m_to_z=us%m_to_Z, answers_2018=cs%hor_regrid_answers_2018)
930 i = cs%col_i(c) ; j = cs%col_j(c)
931 cs%Ref_val_u%p(1:nz_data,c) = sp_val(i,j,1:nz_data)
934 deallocate (sp_val, mask_z)
936 nz_data = cs%Ref_val_v%nz_data
937 allocate(sp_val(g%isd:g%ied,g%jsdB:g%jedB,1:nz_data))
938 allocate(mask_z(g%isd:g%ied,g%jsdB:g%jedB,1:nz_data))
940 call horiz_interp_and_extrap_tracer(cs%Ref_val_v%id, time, 1.0, g, sp_val, mask_z, z_in, &
941 z_edges_in, missing_value, .true., .false., .false., &
942 m_to_z=us%m_to_Z, answers_2018=cs%hor_regrid_answers_2018)
950 i = cs%col_i(c) ; j = cs%col_j(c)
951 cs%Ref_val_v%p(1:nz_data,c) = sp_val(i,j,1:nz_data)
954 deallocate (sp_val, mask_z)
961 i = cs%col_i_u(c) ; j = cs%col_j_u(c)
962 damp = dt * cs%Iresttime_col_u(c)
963 i1pdamp = 1.0 / (1.0 + damp)
964 if (cs%time_varying_sponges) nz_data = cs%Ref_val(m)%nz_data
965 tmp_val2(1:nz_data) = cs%Ref_val_u%p(1:nz_data,c)
966 if (cs%time_varying_sponges)
then 967 call remapping_core_h(cs%remap_cs, nz_data, cs%Ref_val_u%h(:,c), tmp_val2, &
968 cs%nz, hu(i,j,:), tmp_val1, h_neglect, h_neglect_edge)
970 call remapping_core_h(cs%remap_cs, nz_data, cs%Ref_hu%p(:,c), tmp_val2, &
971 cs%nz, hu(i,j,:), tmp_val1, h_neglect, h_neglect_edge)
974 cs%var_u%p(i,j,:) = i1pdamp * (cs%var_u%p(i,j,:) + tmp_val1 * damp)
978 do j=cs%jscB,cs%jecB;
do i=cs%isc,cs%iec;
do k=1,nz
979 hv(i,j,k) = 0.5 * (h(i,j,k) + h(i,j+1,k))
980 enddo ;
enddo ;
enddo 983 i = cs%col_i_v(c) ; j = cs%col_j_v(c)
984 damp = dt * cs%Iresttime_col_v(c)
985 i1pdamp = 1.0 / (1.0 + damp)
986 tmp_val2(1:nz_data) = cs%Ref_val_v%p(1:nz_data,c)
987 if (cs%time_varying_sponges)
then 988 call remapping_core_h(cs%remap_cs, cs%nz_data, cs%Ref_val_v%h(:,c), tmp_val2, &
989 cs%nz, hv(i,j,:), tmp_val1, h_neglect, h_neglect_edge)
991 call remapping_core_h(cs%remap_cs, cs%nz_data, cs%Ref_hv%p(:,c), tmp_val2, &
992 cs%nz, hv(i,j,:), tmp_val1, h_neglect, h_neglect_edge)
995 cs%var_v%p(i,j,:) = i1pdamp * (cs%var_v%p(i,j,:) + tmp_val1 * damp)
1000 deallocate(tmp_val2)