Skip to content

Commit 82b879e

Browse files
Merge pull request mom-ocean#117 from Hallberg-NOAA/Bering_domain_rescaling_fix
+Fix some rescaling issues smoked out by the regional Bering domain
2 parents e73c231 + ed850e2 commit 82b879e

16 files changed

Lines changed: 113 additions & 128 deletions

src/ALE/MOM_ALE.F90

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ subroutine ALE_regrid_accelerated(CS, G, GV, h, tv, n_itt, u, v, OBC, Reg, dt, d
718718
! we have to keep track of the total dzInterface if for some reason
719719
! we're using the old remapping algorithm for u/v
720720
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzInterface, dzIntTotal
721+
real :: h_neglect, h_neglect_edge ! small thicknesses [H ~> m or kg m-2]
721722

722723
nz = GV%ke
723724

@@ -743,7 +744,17 @@ subroutine ALE_regrid_accelerated(CS, G, GV, h, tv, n_itt, u, v, OBC, Reg, dt, d
743744
if (present(dt)) &
744745
call ALE_update_regrid_weights(dt, CS)
745746

747+
if (.not. CS%answers_2018) then
748+
h_neglect = GV%H_subroundoff ; h_neglect_edge = GV%H_subroundoff
749+
elseif (GV%Boussinesq) then
750+
h_neglect = GV%m_to_H * 1.0e-30 ; h_neglect_edge = GV%m_to_H * 1.0e-10
751+
else
752+
h_neglect = GV%kg_m2_to_H * 1.0e-30 ; h_neglect_edge = GV%kg_m2_to_H * 1.0e-10
753+
endif
754+
755+
746756
do itt = 1, n_itt
757+
747758
call do_group_pass(pass_T_S_h, G%domain)
748759

749760
! generate new grid
@@ -753,8 +764,10 @@ subroutine ALE_regrid_accelerated(CS, G, GV, h, tv, n_itt, u, v, OBC, Reg, dt, d
753764

754765
! remap from original grid onto new grid
755766
do j = G%jsc-1,G%jec+1 ; do i = G%isc-1,G%iec+1
756-
call remapping_core_h(CS%remapCS, nz, h_orig(i,j,:), tv%S(i,j,:), nz, h(i,j,:), tv_local%S(i,j,:))
757-
call remapping_core_h(CS%remapCS, nz, h_orig(i,j,:), tv%T(i,j,:), nz, h(i,j,:), tv_local%T(i,j,:))
767+
call remapping_core_h(CS%remapCS, nz, h_orig(i,j,:), tv%S(i,j,:), nz, h(i,j,:), tv_local%S(i,j,:), &
768+
h_neglect, h_neglect_edge)
769+
call remapping_core_h(CS%remapCS, nz, h_orig(i,j,:), tv%T(i,j,:), nz, h(i,j,:), tv_local%T(i,j,:), &
770+
h_neglect, h_neglect_edge)
758771
enddo ; enddo
759772

760773
! starting grid for next iteration

src/core/MOM_barotropic.F90

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module MOM_barotropic
1717
use MOM_grid, only : ocean_grid_type
1818
use MOM_hor_index, only : hor_index_type
1919
use MOM_io, only : vardesc, var_desc, MOM_read_data, slasher
20-
use MOM_open_boundary, only : ocean_OBC_type, OBC_SIMPLE, OBC_NONE, open_boundary_query
20+
use MOM_open_boundary, only : ocean_OBC_type, OBC_NONE, open_boundary_query
2121
use MOM_open_boundary, only : OBC_DIRECTION_E, OBC_DIRECTION_W
2222
use MOM_open_boundary, only : OBC_DIRECTION_N, OBC_DIRECTION_S, OBC_segment_type
2323
use MOM_restart, only : register_restart_field, register_restart_pair
@@ -1245,13 +1245,13 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
12451245
if (Htot_avg*CS%dy_Cu(I,j) <= 0.0) then
12461246
CS%IDatu(I,j) = 0.0
12471247
elseif (integral_BT_cont) then
1248-
CS%IDatu(I,j) = CS%dy_Cu(I,j) / (max(find_duhbt_du(ubt(I,j)*dt, BTCL_u(I,j)), &
1248+
CS%IDatu(I,j) = GV%Z_to_H * CS%dy_Cu(I,j) / (max(find_duhbt_du(ubt(I,j)*dt, BTCL_u(I,j)), &
12491249
CS%dy_Cu(I,j)*Htot_avg) )
12501250
elseif (use_BT_cont) then ! Reconsider the max and whether there should be some scaling.
1251-
CS%IDatu(I,j) = CS%dy_Cu(I,j) / (max(find_duhbt_du(ubt(I,j), BTCL_u(I,j)), &
1251+
CS%IDatu(I,j) = GV%Z_to_H * CS%dy_Cu(I,j) / (max(find_duhbt_du(ubt(I,j), BTCL_u(I,j)), &
12521252
CS%dy_Cu(I,j)*Htot_avg) )
12531253
else
1254-
CS%IDatu(I,j) = 1.0 / Htot_avg
1254+
CS%IDatu(I,j) = GV%Z_to_H / Htot_avg
12551255
endif
12561256
endif
12571257

@@ -1271,13 +1271,13 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
12711271
if (Htot_avg*CS%dx_Cv(i,J) <= 0.0) then
12721272
CS%IDatv(i,J) = 0.0
12731273
elseif (integral_BT_cont) then
1274-
CS%IDatv(i,J) = CS%dx_Cv(i,J) / (max(find_dvhbt_dv(vbt(i,J)*dt, BTCL_v(i,J)), &
1274+
CS%IDatv(i,J) = GV%Z_to_H * CS%dx_Cv(i,J) / (max(find_dvhbt_dv(vbt(i,J)*dt, BTCL_v(i,J)), &
12751275
CS%dx_Cv(i,J)*Htot_avg) )
12761276
elseif (use_BT_cont) then ! Reconsider the max and whether there should be some scaling.
1277-
CS%IDatv(i,J) = CS%dx_Cv(i,J) / (max(find_dvhbt_dv(vbt(i,J), BTCL_v(i,J)), &
1277+
CS%IDatv(i,J) = GV%Z_to_H * CS%dx_Cv(i,J) / (max(find_dvhbt_dv(vbt(i,J), BTCL_v(i,J)), &
12781278
CS%dx_Cv(i,J)*Htot_avg) )
12791279
else
1280-
CS%IDatv(i,J) = 1.0 / Htot_avg
1280+
CS%IDatv(i,J) = GV%Z_to_H / Htot_avg
12811281
endif
12821282
endif
12831283

src/core/MOM_open_boundary.F90

Lines changed: 37 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ module MOM_open_boundary
4848
public open_boundary_test_extern_uv
4949
public open_boundary_test_extern_h
5050
public open_boundary_zero_normal_flow
51+
public parse_segment_str
52+
public parse_segment_manifest_str
53+
public parse_segment_data_str
5154
public register_OBC, OBC_registry_init
5255
public register_file_OBC, file_OBC_end
5356
public segment_tracer_registry_init
@@ -61,12 +64,10 @@ module MOM_open_boundary
6164
public rotate_OBC_config
6265
public rotate_OBC_init
6366
public initialize_segment_data
67+
public flood_fill
68+
public flood_fill2
6469

6570
integer, parameter, public :: OBC_NONE = 0 !< Indicates the use of no open boundary
66-
integer, parameter, public :: OBC_SIMPLE = 1 !< Indicates the use of a simple inflow open boundary
67-
integer, parameter, public :: OBC_WALL = 2 !< Indicates the use of a closed wall
68-
integer, parameter, public :: OBC_FLATHER = 3 !< Indicates the use of a Flather open boundary
69-
integer, parameter, public :: OBC_RADIATION = 4 !< Indicates the use of a radiation open boundary
7071
integer, parameter, public :: OBC_DIRECTION_N = 100 !< Indicates the boundary is an effective northern boundary
7172
integer, parameter, public :: OBC_DIRECTION_S = 200 !< Indicates the boundary is an effective southern boundary
7273
integer, parameter, public :: OBC_DIRECTION_E = 300 !< Indicates the boundary is an effective eastern boundary
@@ -310,6 +311,9 @@ module MOM_open_boundary
310311
real :: ramp_value !< If ramp is True, where we are on the ramp from
311312
!! zero to one [nondim].
312313
type(time_type) :: ramp_start_time !< Time when model was started.
314+
logical :: answers_2018 !< If true, use the order of arithmetic and expressions for remapping
315+
!! that recover the answers from the end of 2018. Otherwise, use more
316+
!! robust and accurate forms of mathematically equivalent expressions.
313317
end type ocean_OBC_type
314318

315319
!> Control structure for open boundaries that read from files.
@@ -607,15 +611,15 @@ subroutine open_boundary_config(G, US, param_file, OBC)
607611
call get_param(param_file, mdl, "DEFAULT_2018_ANSWERS", default_2018_answers, &
608612
"This sets the default value for the various _2018_ANSWERS parameters.", &
609613
default=.false.)
610-
call get_param(param_file, mdl, "REMAPPING_2018_ANSWERS", answers_2018, &
614+
call get_param(param_file, mdl, "REMAPPING_2018_ANSWERS", OBC%answers_2018, &
611615
"If true, use the order of arithmetic and expressions that recover the "//&
612616
"answers from the end of 2018. Otherwise, use updated and more robust "//&
613617
"forms of the same expressions.", default=default_2018_answers)
614618

615619
allocate(OBC%remap_CS)
616620
call initialize_remapping(OBC%remap_CS, remappingScheme, boundary_extrapolation = .false., &
617621
check_reconstruction=check_reconstruction, check_remapping=check_remapping, &
618-
force_bounds_in_subcell=force_bounds_in_subcell, answers_2018=answers_2018)
622+
force_bounds_in_subcell=force_bounds_in_subcell, answers_2018=OBC%answers_2018)
619623

620624
endif ! OBC%number_of_segments > 0
621625

@@ -1693,88 +1697,6 @@ subroutine parse_for_tracer_reservoirs(OBC, PF, use_temperature)
16931697

16941698
end subroutine parse_for_tracer_reservoirs
16951699

1696-
!> Parse an OBC_SEGMENT_%%%_PARAMS string
1697-
subroutine parse_segment_param_real(segment_str, var, param_value, debug )
1698-
character(len=*), intent(in) :: segment_str !< A string in form of
1699-
!! "VAR1=file:foo1.nc(varnam1),VAR2=file:foo2.nc(varnam2),..."
1700-
character(len=*), intent(in) :: var !< The name of the variable for which parameters are needed
1701-
real, intent(out) :: param_value !< The value of the parameter
1702-
logical, optional, intent(in) :: debug !< If present and true, write verbose debugging messages
1703-
! Local variables
1704-
character(len=128) :: word1, word2, word3, method
1705-
integer :: lword, nfields, n, m
1706-
logical :: continue,dbg
1707-
character(len=32), dimension(MAX_OBC_FIELDS) :: flds
1708-
1709-
nfields = 0
1710-
continue = .true.
1711-
dbg = .false.
1712-
if (PRESENT(debug)) dbg = debug
1713-
1714-
do while (continue)
1715-
word1 = extract_word(segment_str,',',nfields+1)
1716-
if (trim(word1) == '') exit
1717-
nfields = nfields+1
1718-
word2 = extract_word(word1,'=',1)
1719-
flds(nfields) = trim(word2)
1720-
enddo
1721-
1722-
! if (PRESENT(fields)) then
1723-
! do n=1,nfields
1724-
! fields(n) = flds(n)
1725-
! enddo
1726-
! endif
1727-
1728-
! if (PRESENT(num_fields)) then
1729-
! num_fields = nfields
1730-
! return
1731-
! endif
1732-
1733-
m=0
1734-
! if (PRESENT(var)) then
1735-
do n=1,nfields
1736-
if (trim(var)==trim(flds(n))) then
1737-
m = n
1738-
exit
1739-
endif
1740-
enddo
1741-
if (m==0) then
1742-
error stop
1743-
endif
1744-
1745-
! Process first word which will start with the fieldname
1746-
word3 = extract_word(segment_str,',',m)
1747-
! word1 = extract_word(word3,':',1)
1748-
! if (trim(word1) == '') exit
1749-
word2 = extract_word(word1,'=',1)
1750-
if (trim(word2) == trim(var)) then
1751-
method=trim(extract_word(word1,'=',2))
1752-
lword=len_trim(method)
1753-
read(method(1:lword),*,err=987) param_value
1754-
! if (method(lword-3:lword) == 'file') then
1755-
! ! raise an error id filename/fieldname not in argument list
1756-
! word1 = extract_word(word3,':',2)
1757-
! filenam = extract_word(word1,'(',1)
1758-
! fieldnam = extract_word(word1,'(',2)
1759-
! lword=len_trim(fieldnam)
1760-
! fieldnam = fieldnam(1:lword-1) ! remove trailing parenth
1761-
! value=-999.
1762-
! elseif (method(lword-4:lword) == 'value') then
1763-
! filenam = 'none'
1764-
! fieldnam = 'none'
1765-
! word1 = extract_word(word3,':',2)
1766-
! lword=len_trim(word1)
1767-
! read(word1(1:lword),*,end=986,err=987) value
1768-
! endif
1769-
endif
1770-
! endif
1771-
1772-
return
1773-
986 call MOM_error(FATAL,'End of record while parsing segment data specification! '//trim(segment_str))
1774-
987 call MOM_error(FATAL,'Error while parsing segment parameter specification! '//trim(segment_str))
1775-
1776-
end subroutine parse_segment_param_real
1777-
17781700
!> Initialize open boundary control structure and do any necessary rescaling of OBC
17791701
!! fields that have been read from a restart file.
17801702
subroutine open_boundary_init(G, GV, US, param_file, OBC, restart_CS)
@@ -3722,6 +3644,7 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
37223644
real, allocatable :: normal_trans_bt(:,:) ! barotropic transport [H L2 T-1 ~> m3 s-1]
37233645
integer :: turns ! Number of index quarter turns
37243646
real :: time_delta ! Time since tidal reference date [T ~> s]
3647+
real :: h_neglect, h_neglect_edge ! Small thicknesses [H ~> m or kg m-2]
37253648

37263649
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec
37273650
isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed
@@ -3734,6 +3657,14 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
37343657

37353658
if (OBC%add_tide_constituents) time_delta = US%s_to_T * time_type_to_real(Time - OBC%time_ref)
37363659

3660+
if (.not. OBC%answers_2018) then
3661+
h_neglect = GV%H_subroundoff ; h_neglect_edge = GV%H_subroundoff
3662+
elseif (GV%Boussinesq) then
3663+
h_neglect = GV%m_to_H * 1.0e-30 ; h_neglect_edge = GV%m_to_H * 1.0e-10
3664+
else
3665+
h_neglect = GV%kg_m2_to_H * 1.0e-30 ; h_neglect_edge = GV%kg_m2_to_H * 1.0e-10
3666+
endif
3667+
37373668
do n = 1, OBC%number_of_segments
37383669
segment => OBC%segment(n)
37393670

@@ -3932,7 +3863,8 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
39323863
! no dz for tidal variables
39333864
if (segment%field(m)%nk_src > 1 .and.&
39343865
(index(segment%field(m)%name, 'phase') <= 0 .and. index(segment%field(m)%name, 'amp') <= 0)) then
3935-
call time_interp_external(segment%field(m)%fid_dz,Time, tmp_buffer_in)
3866+
call time_interp_external(segment%field(m)%fid_dz, Time, tmp_buffer_in)
3867+
tmp_buffer_in(:,:,:) = tmp_buffer_in(:,:,:) * US%m_to_Z
39363868
if (turns /= 0) then
39373869
! TODO: This is hardcoded for 90 degrees, and needs to be generalized.
39383870
if (segment%is_E_or_W &
@@ -3998,19 +3930,22 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
39983930
call remapping_core_h(OBC%remap_CS, &
39993931
segment%field(m)%nk_src,segment%field(m)%dz_src(I,J,:), &
40003932
segment%field(m)%buffer_src(I,J,:), &
4001-
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:))
3933+
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:), &
3934+
h_neglect, h_neglect_edge)
40023935
elseif (G%mask2dCu(I,j)>0.) then
40033936
h_stack(:) = h(i+ishift,j,:)
40043937
call remapping_core_h(OBC%remap_CS, &
40053938
segment%field(m)%nk_src,segment%field(m)%dz_src(I,J,:), &
40063939
segment%field(m)%buffer_src(I,J,:), &
4007-
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:))
3940+
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:), &
3941+
h_neglect, h_neglect_edge)
40083942
elseif (G%mask2dCu(I,j+1)>0.) then
40093943
h_stack(:) = h(i+ishift,j+1,:)
40103944
call remapping_core_h(OBC%remap_CS, &
40113945
segment%field(m)%nk_src,segment%field(m)%dz_src(I,j,:), &
40123946
segment%field(m)%buffer_src(I,J,:), &
4013-
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:))
3947+
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:), &
3948+
h_neglect, h_neglect_edge)
40143949
endif
40153950
enddo
40163951
else
@@ -4025,7 +3960,8 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
40253960
call remapping_core_h(OBC%remap_CS, &
40263961
segment%field(m)%nk_src, scl_fac*segment%field(m)%dz_src(I,j,:), &
40273962
segment%field(m)%buffer_src(I,j,:), &
4028-
GV%ke, h(i+ishift,j,:), segment%field(m)%buffer_dst(I,j,:))
3963+
GV%ke, h(i+ishift,j,:), segment%field(m)%buffer_dst(I,j,:), &
3964+
h_neglect, h_neglect_edge)
40293965
endif
40303966
enddo
40313967
endif
@@ -4044,19 +3980,22 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
40443980
call remapping_core_h(OBC%remap_CS, &
40453981
segment%field(m)%nk_src,segment%field(m)%dz_src(I,J,:), &
40463982
segment%field(m)%buffer_src(I,J,:), &
4047-
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:))
3983+
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:), &
3984+
h_neglect, h_neglect_edge)
40483985
elseif (G%mask2dCv(i,J)>0.) then
40493986
h_stack(:) = h(i,j+jshift,:)
40503987
call remapping_core_h(OBC%remap_CS, &
40513988
segment%field(m)%nk_src,segment%field(m)%dz_src(I,J,:), &
40523989
segment%field(m)%buffer_src(I,J,:), &
4053-
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:))
3990+
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:), &
3991+
h_neglect, h_neglect_edge)
40543992
elseif (G%mask2dCv(i+1,J)>0.) then
40553993
h_stack(:) = h(i+1,j+jshift,:)
40563994
call remapping_core_h(OBC%remap_CS, &
40573995
segment%field(m)%nk_src,segment%field(m)%dz_src(I,J,:), &
40583996
segment%field(m)%buffer_src(I,J,:), &
4059-
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:))
3997+
GV%ke, h_stack, segment%field(m)%buffer_dst(I,J,:), &
3998+
h_neglect, h_neglect_edge)
40603999
endif
40614000
enddo
40624001
else
@@ -4071,7 +4010,8 @@ subroutine update_OBC_segment_data(G, GV, US, OBC, tv, h, Time)
40714010
call remapping_core_h(OBC%remap_CS, &
40724011
segment%field(m)%nk_src, scl_fac*segment%field(m)%dz_src(i,J,:), &
40734012
segment%field(m)%buffer_src(i,J,:), &
4074-
GV%ke, h(i,j+jshift,:), segment%field(m)%buffer_dst(i,J,:))
4013+
GV%ke, h(i,j+jshift,:), segment%field(m)%buffer_dst(i,J,:), &
4014+
h_neglect, h_neglect_edge)
40754015
endif
40764016
enddo
40774017
endif

src/framework/MOM_horizontal_regridding.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ subroutine horiz_interp_and_extrap_tracer_fms_id(fms_id, Time, conversion, G, t
856856
do k=1,kd
857857
do j=js,je
858858
do i=is,ie
859-
tr_z(i,j,k)=data_in(i,j,k)
859+
tr_z(i,j,k)=data_in(i,j,k) * conversion
860860
if (.not. ans_2018) mask_z(i,j,k) = 1.
861861
if (abs(tr_z(i,j,k)-missing_value) < abs(roundoff*missing_value)) mask_z(i,j,k) = 0.
862862
enddo

src/initialization/MOM_state_initialization.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module MOM_state_initialization
2020
use MOM_interface_heights, only : find_eta
2121
use MOM_io, only : file_exists, field_size, MOM_read_data, MOM_read_vector, slasher
2222
use MOM_open_boundary, only : ocean_OBC_type, open_boundary_init, set_tracer_data
23-
use MOM_open_boundary, only : OBC_NONE, OBC_SIMPLE
23+
use MOM_open_boundary, only : OBC_NONE
2424
use MOM_open_boundary, only : open_boundary_query
2525
use MOM_open_boundary, only : set_tracer_data, initialize_segment_data
2626
use MOM_open_boundary, only : open_boundary_test_extern_h

0 commit comments

Comments
 (0)