MOM6
dyed_channel_initialization.F90
1 !> Initialization for the dyed_channel configuration
3 
4 ! This file is part of MOM6. See LICENSE.md for the license.
5 
7 use mom_error_handler, only : mom_mesg, mom_error, fatal, warning, is_root_pe
9 use mom_get_input, only : directories
10 use mom_grid, only : ocean_grid_type
11 use mom_open_boundary, only : ocean_obc_type, obc_none, obc_simple
12 use mom_open_boundary, only : obc_segment_type, register_segment_tracer
13 use mom_open_boundary, only : obc_registry_type, register_obc
14 use mom_time_manager, only : time_type, time_type_to_real
15 use mom_tracer_registry, only : tracer_registry_type, tracer_name_lookup
19 
20 implicit none ; private
21 
22 #include <MOM_memory.h>
23 
24 public dyed_channel_set_obc_tracer_data, dyed_channel_obc_end
25 public register_dyed_channel_obc, dyed_channel_update_flow
26 
27 !> Control structure for dyed-channel open boundaries.
28 type, public :: dyed_channel_obc_cs ; private
29  real :: zonal_flow = 8.57 !< Mean inflow
30  real :: tidal_amp = 0.0 !< Sloshing amplitude
31  real :: frequency = 0.0 !< Sloshing frequency
32 end type dyed_channel_obc_cs
33 
34 integer :: ntr = 0 !< Number of dye tracers
35  !! \todo This is a module variable. Move this variable into the control structure.
36 
37 contains
38 
39 !> Add dyed channel to OBC registry.
40 function register_dyed_channel_obc(param_file, CS, OBC_Reg)
41  type(param_file_type), intent(in) :: param_file !< parameter file.
42  type(dyed_channel_obc_cs), pointer :: cs !< Dyed channel control structure.
43  type(obc_registry_type), pointer :: obc_reg !< OBC registry.
44  ! Local variables
45  logical :: register_dyed_channel_obc
46  character(len=32) :: casename = "dyed channel" ! This case's name.
47  character(len=40) :: mdl = "register_dyed_channel_OBC" ! This subroutine's name.
48 
49  if (associated(cs)) then
50  call mom_error(warning, "register_dyed_channel_OBC called with an "// &
51  "associated control structure.")
52  return
53  endif
54  allocate(cs)
55 
56  call get_param(param_file, mdl, "CHANNEL_MEAN_FLOW", cs%zonal_flow, &
57  "Mean zonal flow imposed at upstream open boundary.", &
58  units="m/s", default=8.57)
59  call get_param(param_file, mdl, "CHANNEL_TIDAL_AMP", cs%tidal_amp, &
60  "Sloshing amplitude imposed at upstream open boundary.", &
61  units="m/s", default=0.0)
62  call get_param(param_file, mdl, "CHANNEL_FLOW_FREQUENCY", cs%frequency, &
63  "Frequency of oscillating zonal flow.", &
64  units="s-1", default=0.0)
65 
66  ! Register the open boundaries.
67  call register_obc(casename, param_file, obc_reg)
68  register_dyed_channel_obc = .true.
69 
70 end function register_dyed_channel_obc
71 
72 !> Clean up the dyed_channel OBC from registry.
73 subroutine dyed_channel_obc_end(CS)
74  type(dyed_channel_obc_cs), pointer :: cs !< Dyed channel control structure.
75 
76  if (associated(cs)) then
77  deallocate(cs)
78  endif
79 end subroutine dyed_channel_obc_end
80 
81 !> This subroutine sets the dye and flow properties at open boundary conditions.
82 subroutine dyed_channel_set_obc_tracer_data(OBC, G, GV, param_file, tr_Reg)
83  type(ocean_obc_type), pointer :: obc !< This open boundary condition type specifies
84  !! whether, where, and what open boundary
85  !! conditions are used.
86  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
87  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
88  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
89  !! to parse for model parameter values.
90  type(tracer_registry_type), pointer :: tr_reg !< Tracer registry.
91  ! Local variables
92  character(len=40) :: mdl = "dyed_channel_set_OBC_tracer_data" ! This subroutine's name.
93  character(len=80) :: name, longname
94  integer :: i, j, k, l, itt, isd, ied, jsd, jed, m, n
95  integer :: isdb, iedb, jsdb, jedb
96  real :: dye
97  type(obc_segment_type), pointer :: segment => null()
98  type(tracer_type), pointer :: tr_ptr => null()
99 
100  if (.not.associated(obc)) call mom_error(fatal, 'dyed_channel_initialization.F90: '// &
101  'dyed_channel_set_OBC_data() was called but OBC type was not initialized!')
102 
103  call get_param(param_file, mdl, "NUM_DYE_TRACERS", ntr, &
104  "The number of dye tracers in this run. Each tracer "//&
105  "should have a separate boundary segment.", default=0, &
106  do_not_log=.true.)
107 
108  if (obc%number_of_segments < ntr) then
109  call mom_error(warning, "Error in dyed_obc segment setup")
110  return !!! Need a better error message here
111  endif
112 
113 ! ! Set the inflow values of the dyes, one per segment.
114 ! ! We know the order: north, south, east, west
115  do m=1,ntr
116  write(name,'("dye_",I2.2)') m
117  write(longname,'("Concentration of dyed_obc Tracer ",I2.2, " on segment ",I2.2)') m, m
118  call tracer_name_lookup(tr_reg, tr_ptr, name)
119 
120  do n=1,obc%number_of_segments
121  if (n == m) then
122  dye = 1.0
123  else
124  dye = 0.0
125  endif
126  call register_segment_tracer(tr_ptr, param_file, gv, &
127  obc%segment(n), obc_scalar=dye)
128  enddo
129  enddo
130 
131 end subroutine dyed_channel_set_obc_tracer_data
132 
133 !> This subroutine updates the long-channel flow
134 subroutine dyed_channel_update_flow(OBC, CS, G, Time)
135  type(ocean_obc_type), pointer :: obc !< This open boundary condition type specifies
136  !! whether, where, and what open boundary
137  !! conditions are used.
138  type(dyed_channel_obc_cs), pointer :: cs !< Dyed channel control structure.
139  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
140  type(time_type), intent(in) :: time !< model time.
141  ! Local variables
142  character(len=40) :: mdl = "dyed_channel_update_flow" ! This subroutine's name.
143  character(len=80) :: name
144  real :: flow, time_sec, pi
145  integer :: i, j, k, l, itt, isd, ied, jsd, jed, m, n
146  integer :: isdb, iedb, jsdb, jedb
147  type(obc_segment_type), pointer :: segment => null()
148 
149  if (.not.associated(obc)) call mom_error(fatal, 'dyed_channel_initialization.F90: '// &
150  'dyed_channel_update_flow() was called but OBC type was not initialized!')
151 
152  time_sec = time_type_to_real(time)
153  pi = 4.0*atan(1.0)
154 
155  do l=1, obc%number_of_segments
156  segment => obc%segment(l)
157  if (.not. segment%on_pe) cycle
158  if (segment%gradient) cycle
159  if (segment%oblique .and. .not. segment%nudged .and. .not. segment%Flather) cycle
160 
161  if (segment%is_E_or_W) then
162  jsd = segment%HI%jsd ; jed = segment%HI%jed
163  isdb = segment%HI%IsdB ; iedb = segment%HI%IedB
164  if (cs%frequency == 0.0) then
165  flow = g%US%m_s_to_L_T*cs%zonal_flow
166  else
167  flow = g%US%m_s_to_L_T*cs%zonal_flow + cs%tidal_amp * cos(2 * pi * cs%frequency * time_sec)
168  endif
169  do k=1,g%ke
170  do j=jsd,jed ; do i=isdb,iedb
171  if (segment%specified .or. segment%nudged) then
172  segment%normal_vel(i,j,k) = flow
173  endif
174  if (segment%specified) then
175  segment%normal_trans(i,j,k) = flow * g%dyCu(i,j)
176  endif
177  enddo ; enddo
178  enddo
179  do j=jsd,jed ; do i=isdb,iedb
180  segment%normal_vel_bt(i,j) = flow
181  enddo ; enddo
182  else
183  isd = segment%HI%isd ; ied = segment%HI%ied
184  jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
185  do j=jsdb,jedb ; do i=isd,ied
186  segment%normal_vel_bt(i,j) = 0.0
187  enddo ; enddo
188  endif
189  enddo
190 
191 end subroutine dyed_channel_update_flow
192 
193 !> \namespace dyed_channel_initialization
194 !!
195 !! Setting dyes, one for painting the inflow on each side.
Wraps the FMS time manager functions.
Control structure for dyed-channel open boundaries.
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:26
Reads the only Fortran name list needed to boot-strap the model.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
Definition: MOM_grid.F90:2
Open boundary segment data structure.
Describes the horizontal ocean grid with only dynamic memory arrays.
The MOM6 facility to parse input files for runtime parameters.
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
Type to carry basic OBC information needed for updating values.
Type to carry basic tracer information.
Routines for error handling and I/O management.
Initialization for the dyed_channel configuration.
An overloaded interface to log version information about modules.
Describes the vertical ocean grid, including unit conversion factors.
Container for paths and parameter file names.
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Contains a shareable dynamic type for describing horizontal grids and metric data and utilty routines...
Controls where open boundary conditions are applied.
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.