@@ -353,25 +353,27 @@ module MOM_open_boundary
353353 type (remapping_CS), pointer :: remap_h_CS= > NULL () ! < ALE remapping control structure for
354354 ! ! thickness-based fields on segments
355355 type (OBC_registry_type), pointer :: OBC_Reg = > NULL () ! < Registry type for boundaries
356- real , allocatable :: rx_normal(:,:,:) ! < Array storage for normal phase speed for EW radiation OBCs in units of
357- ! ! grid points per timestep [nondim]
358- real , allocatable :: ry_normal(:,:,:) ! < Array storage for normal phase speed for NS radiation OBCs in units of
359- ! ! grid points per timestep [nondim]
360- real , allocatable :: rx_oblique_u(:,:,:) ! < X-direction oblique boundary condition radiation speeds squared
361- ! ! at u points for restarts [L2 T-2 ~> m2 s-2]
362- real , allocatable :: ry_oblique_u(:,:,:) ! < Y-direction oblique boundary condition radiation speeds squared
363- ! ! at u points for restarts [L2 T-2 ~> m2 s-2]
364- real , allocatable :: rx_oblique_v(:,:,:) ! < X-direction oblique boundary condition radiation speeds squared
365- ! ! at v points for restarts [L2 T-2 ~> m2 s-2]
366- real , allocatable :: ry_oblique_v(:,:,:) ! < Y-direction oblique boundary condition radiation speeds squared
367- ! ! at v points for restarts [L2 T-2 ~> m2 s-2]
368- real , allocatable :: cff_normal_u(:,:,:) ! < Denominator for normalizing EW oblique boundary condition radiation
369- ! ! rates at u points for restarts [L2 T-2 ~> m2 s-2]
370- real , allocatable :: cff_normal_v(:,:,:) ! < Denominator for normalizing NS oblique boundary condition radiation
371- ! ! rates at v points for restarts [L2 T-2 ~> m2 s-2]
372- real , allocatable :: tres_x(:,:,:,:) ! < Array storage of tracer reservoirs for restarts, in unscaled units [conc]
373- real , allocatable :: tres_y(:,:,:,:) ! < Array storage of tracer reservoirs for restarts, in unscaled units [conc]
374- logical :: debug ! < If true, write verbose checksums for debugging purposes.
356+ real , pointer :: rx_normal(:,:,:) = > Null () ! < Array storage for normal phase speed for EW radiation OBCs
357+ ! ! in units of grid points per timestep [nondim]
358+ real , pointer :: ry_normal(:,:,:) = > Null () ! < Array storage for normal phase speed for NS radiation OBCs
359+ ! ! in units of grid points per timestep [nondim]
360+ real , pointer :: rx_oblique_u(:,:,:) = > Null () ! < X-direction oblique boundary condition radiation speeds
361+ ! ! squared at u points for restarts [L2 T-2 ~> m2 s-2]
362+ real , pointer :: ry_oblique_u(:,:,:) = > Null () ! < Y-direction oblique boundary condition radiation speeds
363+ ! ! squared at u points for restarts [L2 T-2 ~> m2 s-2]
364+ real , pointer :: rx_oblique_v(:,:,:) = > Null () ! < X-direction oblique boundary condition radiation speeds
365+ ! ! squared at v points for restarts [L2 T-2 ~> m2 s-2]
366+ real , pointer :: ry_oblique_v(:,:,:) = > Null () ! < Y-direction oblique boundary condition radiation speeds
367+ ! ! squared at v points for restarts [L2 T-2 ~> m2 s-2]
368+ real , pointer :: cff_normal_u(:,:,:) = > Null () ! < Denominator for normalizing EW oblique boundary condition
369+ ! ! radiation rates at u points for restarts [L2 T-2 ~> m2 s-2]
370+ real , pointer :: cff_normal_v(:,:,:) = > Null () ! < Denominator for normalizing NS oblique boundary condition
371+ ! ! radiation rates at v points for restarts [L2 T-2 ~> m2 s-2]
372+ real , pointer :: tres_x(:,:,:,:) = > Null () ! < Array storage of tracer reservoirs for restarts,
373+ ! ! in unscaled units [conc]
374+ real , pointer :: tres_y(:,:,:,:) = > Null () ! < Array storage of tracer reservoirs for restarts,
375+ ! ! in unscaled units [conc]
376+ logical :: debug ! < If true, write verbose checksums for debugging purposes.
375377 real :: silly_h ! < A silly value of thickness outside of the domain that can be used to test
376378 ! ! the independence of the OBCs to this external data [Z ~> m].
377379 real :: silly_u ! < A silly value of velocity outside of the domain that can be used to test
@@ -1963,15 +1965,15 @@ subroutine open_boundary_init(G, GV, US, param_file, OBC, restart_CS)
19631965 call create_group_pass(OBC% pass_oblique, OBC% cff_normal_u, OBC% cff_normal_v, G% Domain, To_All+ Scalar_Pair)
19641966 call do_group_pass(OBC% pass_oblique, G% Domain)
19651967 endif
1966- if (allocated (OBC% tres_x) .and. allocated (OBC% tres_y)) then
1968+ if (associated (OBC% tres_x) .and. associated (OBC% tres_y)) then
19671969 do m= 1 ,OBC% ntr
19681970 call pass_vector(OBC% tres_x(:,:,:,m), OBC% tres_y(:,:,:,m), G% Domain, To_All+ Scalar_Pair)
19691971 enddo
1970- elseif (allocated (OBC% tres_x)) then
1972+ elseif (associated (OBC% tres_x)) then
19711973 do m= 1 ,OBC% ntr
19721974 call pass_var(OBC% tres_x(:,:,:,m), G% Domain, position= EAST_FACE)
19731975 enddo
1974- elseif (allocated (OBC% tres_y)) then
1976+ elseif (associated (OBC% tres_y)) then
19751977 do m= 1 ,OBC% ntr
19761978 call pass_var(OBC% tres_y(:,:,:,m), G% Domain, position= NORTH_FACE)
19771979 enddo
@@ -2016,16 +2018,27 @@ subroutine open_boundary_dealloc(OBC)
20162018 if (allocated (OBC% segment)) deallocate (OBC% segment)
20172019 if (allocated (OBC% segnum_u)) deallocate (OBC% segnum_u)
20182020 if (allocated (OBC% segnum_v)) deallocate (OBC% segnum_v)
2019- if (allocated (OBC% rx_normal)) deallocate (OBC% rx_normal)
2020- if (allocated (OBC% ry_normal)) deallocate (OBC% ry_normal)
2021- if (allocated (OBC% rx_oblique_u)) deallocate (OBC% rx_oblique_u)
2022- if (allocated (OBC% ry_oblique_u)) deallocate (OBC% ry_oblique_u)
2023- if (allocated (OBC% rx_oblique_v)) deallocate (OBC% rx_oblique_v)
2024- if (allocated (OBC% ry_oblique_v)) deallocate (OBC% ry_oblique_v)
2025- if (allocated (OBC% cff_normal_u)) deallocate (OBC% cff_normal_u)
2026- if (allocated (OBC% cff_normal_v)) deallocate (OBC% cff_normal_v)
2027- if (allocated (OBC% tres_x)) deallocate (OBC% tres_x)
2028- if (allocated (OBC% tres_y)) deallocate (OBC% tres_y)
2021+ if (associated (OBC% rx_normal)) deallocate (OBC% rx_normal)
2022+ if (associated (OBC% ry_normal)) deallocate (OBC% ry_normal)
2023+ if (associated (OBC% rx_oblique_u)) deallocate (OBC% rx_oblique_u)
2024+ if (associated (OBC% ry_oblique_u)) deallocate (OBC% ry_oblique_u)
2025+ if (associated (OBC% rx_oblique_v)) deallocate (OBC% rx_oblique_v)
2026+ if (associated (OBC% ry_oblique_v)) deallocate (OBC% ry_oblique_v)
2027+ if (associated (OBC% cff_normal_u)) deallocate (OBC% cff_normal_u)
2028+ if (associated (OBC% cff_normal_v)) deallocate (OBC% cff_normal_v)
2029+ if (associated (OBC% tres_x)) deallocate (OBC% tres_x)
2030+ if (associated (OBC% tres_y)) deallocate (OBC% tres_y)
2031+
2032+ if (associated (OBC% rx_normal)) nullify(OBC% rx_normal)
2033+ if (associated (OBC% ry_normal)) nullify(OBC% ry_normal)
2034+ if (associated (OBC% rx_oblique_u)) nullify(OBC% rx_oblique_u)
2035+ if (associated (OBC% ry_oblique_u)) nullify(OBC% ry_oblique_u)
2036+ if (associated (OBC% rx_oblique_v)) nullify(OBC% rx_oblique_v)
2037+ if (associated (OBC% ry_oblique_v)) nullify(OBC% ry_oblique_v)
2038+ if (associated (OBC% cff_normal_u)) nullify(OBC% cff_normal_u)
2039+ if (associated (OBC% cff_normal_v)) nullify(OBC% cff_normal_v)
2040+ if (associated (OBC% tres_x)) nullify(OBC% tres_x)
2041+ if (associated (OBC% tres_y)) nullify(OBC% tres_y)
20292042 if (associated (OBC% remap_z_CS)) deallocate (OBC% remap_z_CS)
20302043 if (associated (OBC% remap_h_CS)) deallocate (OBC% remap_h_CS)
20312044 deallocate (OBC)
@@ -3384,7 +3397,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, GV, US,
33843397 haloshift= 0 , symmetric= sym, unscale= 1.0 / US% L_T_to_m_s** 2 )
33853398 endif
33863399 if (OBC% ntr == 0 ) return
3387- if (.not. allocated (OBC% tres_x) .or. .not. allocated (OBC% tres_y)) return
3400+ if (.not. associated (OBC% tres_x) .or. .not. associated (OBC% tres_y)) return
33883401 do m= 1 ,OBC% ntr
33893402 write (var_num,' (I3.3)' ) m
33903403 call uvchksum(" radiation_OBCs: OBC%tres_[xy]_" // var_num, OBC% tres_x(:,:,:,m), OBC% tres_y(:,:,:,m), G% HI, &
@@ -5504,7 +5517,7 @@ subroutine update_segment_tracer_reservoirs(G, GV, uhr, vhr, h, OBC, dt, Reg)
55045517 ((1.0 - a_out+ a_in)* segment% tr_Reg% Tr(m)% tres(I,j,k)+ &
55055518 ((u_L_out+ a_out)* Reg% Tr(ntr_id)% t(I+ ishift,j,k) - &
55065519 (u_L_in+ a_in)* segment% tr_Reg% Tr(m)% t(I,j,k)))
5507- if (allocated (OBC% tres_x)) OBC% tres_x(I,j,k,m) = I_scale * segment% tr_Reg% Tr(m)% tres(I,j,k)
5520+ if (associated (OBC% tres_x)) OBC% tres_x(I,j,k,m) = I_scale * segment% tr_Reg% Tr(m)% tres(I,j,k)
55085521 enddo ; endif
55095522 enddo
55105523 enddo
@@ -5544,7 +5557,7 @@ subroutine update_segment_tracer_reservoirs(G, GV, uhr, vhr, h, OBC, dt, Reg)
55445557 ((1.0 - a_out+ a_in)* segment% tr_Reg% Tr(m)% tres(i,J,k) + &
55455558 ((v_L_out+ a_out)* Reg% Tr(ntr_id)% t(i,J+ jshift,k) - &
55465559 (v_L_in+ a_in)* segment% tr_Reg% Tr(m)% t(i,J,k)))
5547- if (allocated (OBC% tres_y)) OBC% tres_y(i,J,k,m) = I_scale * segment% tr_Reg% Tr(m)% tres(i,J,k)
5560+ if (associated (OBC% tres_y)) OBC% tres_y(i,J,k,m) = I_scale * segment% tr_Reg% Tr(m)% tres(i,J,k)
55485561 enddo ; endif
55495562 enddo
55505563 enddo
@@ -5620,7 +5633,7 @@ subroutine remap_OBC_fields(G, GV, h_old, h_new, OBC, PCM_cell)
56205633
56215634 ! Update tracer concentrations
56225635 segment% tr_Reg% Tr(m)% tres(I,j,:) = tr_column(:)
5623- if (allocated (OBC% tres_x)) then ; do k= 1 ,nz
5636+ if (associated (OBC% tres_x)) then ; do k= 1 ,nz
56245637 OBC% tres_x(I,j,k,m) = I_scale * segment% tr_Reg% Tr(m)% tres(I,j,k)
56255638 enddo ; endif
56265639
@@ -5687,7 +5700,7 @@ subroutine remap_OBC_fields(G, GV, h_old, h_new, OBC, PCM_cell)
56875700
56885701 ! Update tracer concentrations
56895702 segment% tr_Reg% Tr(m)% tres(i,J,:) = tr_column(:)
5690- if (allocated (OBC% tres_y)) then ; do k= 1 ,nz
5703+ if (associated (OBC% tres_y)) then ; do k= 1 ,nz
56915704 OBC% tres_y(i,J,k,m) = I_scale * segment% tr_Reg% Tr(m)% tres(i,J,k)
56925705 enddo ; endif
56935706
@@ -6070,13 +6083,14 @@ subroutine rotate_OBC_init(OBC_in, G, GV, US, param_file, tv, restart_CS, OBC)
60706083 " If true, Temperature and salinity are used as state " // &
60716084 " variables." , default= .true. , do_not_log= .true. )
60726085
6086+ if (use_temperature) &
6087+ call fill_temp_salt_segments(G, GV, US, OBC, tv)
6088+
60736089 do l = 1 , OBC% number_of_segments
60746090 call rotate_OBC_segment_data(OBC_in% segment(l), OBC% segment(l), G% HI% turns)
60756091 enddo
60766092
6077- if (use_temperature) &
6078- call fill_temp_salt_segments(G, GV, US, OBC, tv)
6079-
6093+ call setup_OBC_tracer_reservoirs(G, GV, OBC)
60806094 call open_boundary_init(G, GV, US, param_file, OBC, restart_CS)
60816095end subroutine rotate_OBC_init
60826096
@@ -6099,6 +6113,14 @@ subroutine rotate_OBC_segment_data(segment_in, segment, turns)
60996113 segment% field(n)% handle = segment_in% field(n)% handle
61006114 segment% field(n)% dz_handle = segment_in% field(n)% dz_handle
61016115
6116+ if (allocated (segment_in% field(n)% buffer_dst)) then
6117+ call allocate_rotated_array(segment_in% field(n)% buffer_dst, &
6118+ lbound (segment_in% field(n)% buffer_dst), turns, &
6119+ segment% field(n)% buffer_dst)
6120+ call rotate_array(segment_in% field(n)% buffer_dst, turns, &
6121+ segment% field(n)% buffer_dst)
6122+ endif
6123+
61026124 if (modulo (turns, 2 ) /= 0 ) then
61036125 select case (segment_in% field(n)% name)
61046126 case (' U' )
@@ -6145,6 +6167,102 @@ subroutine rotate_OBC_segment_data(segment_in, segment, turns)
61456167 segment% field(n)% value = segment_in% field(n)% value
61466168 enddo
61476169
6170+ if (allocated (segment_in% SSH)) &
6171+ call rotate_array(segment_in% SSH, turns, segment% SSH)
6172+ if (allocated (segment_in% cg)) &
6173+ call rotate_array(segment_in% cg, turns, segment% cg)
6174+ if (allocated (segment_in% htot)) &
6175+ call rotate_array(segment_in% htot, turns, segment% htot)
6176+ if (allocated (segment_in% dztot)) &
6177+ call rotate_array(segment_in% dztot, turns, segment% dztot)
6178+ if (allocated (segment_in% h)) &
6179+ call rotate_array(segment_in% h, turns, segment% h)
6180+ if (allocated (segment_in% normal_vel)) &
6181+ call rotate_array(segment_in% normal_vel, turns, segment% normal_vel)
6182+ if (allocated (segment_in% normal_trans)) &
6183+ call rotate_array(segment_in% normal_trans, turns, segment% normal_trans)
6184+ if (allocated (segment_in% normal_vel_bt)) &
6185+ call rotate_array(segment_in% normal_vel_bt, turns, segment% normal_vel_bt)
6186+ if (allocated (segment_in% tangential_vel)) &
6187+ call rotate_array(segment_in% tangential_vel, turns, segment% tangential_vel)
6188+ if (allocated (segment_in% tangential_grad)) &
6189+ call rotate_array(segment_in% tangential_grad, turns, segment% tangential_grad)
6190+ if (allocated (segment_in% grad_normal)) &
6191+ call rotate_array(segment_in% grad_normal, turns, segment% grad_normal)
6192+ if (allocated (segment_in% grad_tan)) &
6193+ call rotate_array(segment_in% grad_tan, turns, segment% grad_tan)
6194+ if (allocated (segment_in% grad_gradient)) &
6195+ call rotate_array(segment_in% grad_gradient, turns, segment% grad_gradient)
6196+ if (modulo (turns, 2 ) /= 0 ) then
6197+ if (allocated (segment_in% rx_norm_rad)) &
6198+ call rotate_array(segment_in% rx_norm_rad, turns, segment% ry_norm_rad)
6199+ if (allocated (segment_in% ry_norm_rad)) &
6200+ call rotate_array(segment_in% ry_norm_rad, turns, segment% rx_norm_rad)
6201+ if (allocated (segment_in% rx_norm_obl)) &
6202+ call rotate_array(segment_in% rx_norm_obl, turns, segment% ry_norm_obl)
6203+ if (allocated (segment_in% ry_norm_obl)) &
6204+ call rotate_array(segment_in% ry_norm_obl, turns, segment% rx_norm_obl)
6205+ else
6206+ if (allocated (segment_in% rx_norm_rad)) &
6207+ call rotate_array(segment_in% rx_norm_rad, turns, segment% rx_norm_rad)
6208+ if (allocated (segment_in% ry_norm_rad)) &
6209+ call rotate_array(segment_in% ry_norm_rad, turns, segment% ry_norm_rad)
6210+ if (allocated (segment_in% rx_norm_obl)) &
6211+ call rotate_array(segment_in% rx_norm_obl, turns, segment% rx_norm_obl)
6212+ if (allocated (segment_in% ry_norm_obl)) &
6213+ call rotate_array(segment_in% ry_norm_obl, turns, segment% ry_norm_obl)
6214+ endif
6215+ if (allocated (segment_in% cff_normal)) &
6216+ call rotate_array(segment_in% cff_normal, turns, segment% cff_normal)
6217+ if (allocated (segment_in% nudged_normal_vel)) &
6218+ call rotate_array(segment_in% nudged_normal_vel, turns, segment% nudged_normal_vel)
6219+ if (allocated (segment_in% nudged_tangential_vel)) &
6220+ call rotate_array(segment_in% nudged_tangential_vel, turns, segment% nudged_tangential_vel)
6221+ if (allocated (segment_in% nudged_tangential_grad)) &
6222+ call rotate_array(segment_in% nudged_tangential_grad, turns, segment% nudged_tangential_grad)
6223+ if (associated (segment_in% tr_Reg)) then
6224+ do n = 1 , segment_in% tr_Reg% ntseg
6225+ call rotate_array(segment_in% tr_Reg% tr(n)% t, turns, segment% tr_Reg% tr(n)% t)
6226+ call rotate_array(segment_in% tr_Reg% tr(n)% tres, turns, segment% tr_Reg% tr(n)% tres)
6227+ ! Testing this to see if it works for contant tres values. Probably wrong otherwise.
6228+ segment% tr_Reg% Tr(n)% is_initialized= .true.
6229+ enddo
6230+ endif
6231+
6232+ do n = 1 , num_fields
6233+ if ((segment% field(n)% name == ' U' .or. segment% field(n)% name == ' Uamp' ) .and. &
6234+ (modulo (turns, 4 ) == 1 .or. modulo (turns, 4 ) == 2 )) then
6235+ segment% field(n)% buffer_dst(:,:,:) = - segment% field(n)% buffer_dst(:,:,:)
6236+ if (segment% is_E_or_W) then
6237+ segment% normal_trans(:,:,:) = - segment% normal_trans(:,:,:)
6238+ segment% normal_vel(:,:,:) = - segment% normal_vel(:,:,:)
6239+ segment% normal_vel_bt(:,:) = - segment% normal_vel_bt(:,:)
6240+ if (allocated (segment% nudged_normal_vel)) &
6241+ segment% nudged_normal_vel(:,:,:) = - segment% nudged_normal_vel(:,:,:)
6242+ else
6243+ if (allocated (segment% tangential_vel)) &
6244+ segment% tangential_vel(:,:,:) = - segment% tangential_vel(:,:,:)
6245+ if (allocated (segment% nudged_tangential_vel)) &
6246+ segment% nudged_tangential_vel(:,:,:) = - segment% nudged_tangential_vel(:,:,:)
6247+ endif
6248+ elseif ((segment% field(n)% name == ' V' .or. segment% field(n)% name == ' Vamp' ) .and. &
6249+ (modulo (turns, 4 ) == 3 .or. modulo (turns, 4 ) == 2 )) then
6250+ segment% field(n)% buffer_dst(:,:,:) = - segment% field(n)% buffer_dst(:,:,:)
6251+ if (segment% is_N_or_S) then
6252+ segment% normal_trans(:,:,:) = - segment% normal_trans(:,:,:)
6253+ segment% normal_vel(:,:,:) = - segment% normal_vel(:,:,:)
6254+ segment% normal_vel_bt(:,:) = - segment% normal_vel_bt(:,:)
6255+ if (allocated (segment% nudged_normal_vel)) &
6256+ segment% nudged_normal_vel(:,:,:) = - segment% nudged_normal_vel(:,:,:)
6257+ else
6258+ if (allocated (segment% tangential_vel)) &
6259+ segment% tangential_vel(:,:,:) = - segment% tangential_vel(:,:,:)
6260+ if (allocated (segment% nudged_tangential_vel)) &
6261+ segment% nudged_tangential_vel(:,:,:) = - segment% nudged_tangential_vel(:,:,:)
6262+ endif
6263+ endif
6264+ enddo
6265+
61486266 segment% temp_segment_data_exists = segment_in% temp_segment_data_exists
61496267 segment% salt_segment_data_exists = segment_in% salt_segment_data_exists
61506268end subroutine rotate_OBC_segment_data
0 commit comments