MOM6
isomip_tracer Module Reference

Detailed Description

Routines used to set up and use a set of (one for now) dynamically passive tracers in the ISOMIP configuration.

For now, just one passive tracer is injected in the sponge layer.

Data Types

type  isomip_tracer_cs
 ISOMIP tracer package control structure. More...
 

Functions/Subroutines

logical function, public register_isomip_tracer (HI, GV, param_file, CS, tr_Reg, restart_CS)
 This subroutine is used to register tracer fields. More...
 
subroutine, public initialize_isomip_tracer (restart, day, G, GV, h, diag, OBC, CS, ALE_sponge_CSp)
 Initializes the NTR tracer fields in tr(:,:,:,:) More...
 
subroutine, public isomip_tracer_column_physics (h_old, h_new, ea, eb, fluxes, dt, G, GV, US, CS, evap_CFL_limit, minimum_forcing_depth)
 This subroutine applies diapycnal diffusion, including the surface boundary conditions and any other column tracer physics or chemistry to the tracers from this file. More...
 
subroutine, public isomip_tracer_surface_state (sfc_state, h, G, CS)
 This subroutine extracts the surface fields from this tracer package that are to be shared with the atmosphere in coupled configurations. This particular tracer package does not report anything back to the coupler. More...
 
subroutine, public isomip_tracer_end (CS)
 Deallocate any memory used by the ISOMIP tracer package. More...
 

Variables

integer, parameter ntr = 1
 ntr is the number of tracers in this module.
 

Function/Subroutine Documentation

◆ initialize_isomip_tracer()

subroutine, public isomip_tracer::initialize_isomip_tracer ( logical, intent(in)  restart,
type(time_type), intent(in), target  day,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
type(diag_ctrl), intent(in), target  diag,
type(ocean_obc_type), pointer  OBC,
type(isomip_tracer_cs), pointer  CS,
type(ale_sponge_cs), pointer  ALE_sponge_CSp 
)

Initializes the NTR tracer fields in tr(:,:,:,:)

Parameters
[in]gGrid structure.
[in]gvThe ocean's vertical grid structure.
[in]restart.true. if the fields have already been read from a restart file.
[in]dayTime of the start of the run.
[in]hLayer thickness [H ~> m or kg m-2].
[in]diagA structure that is used to regulate diagnostic output.
obcThis open boundary condition type specifies whether, where, and what open boundary conditions are used. This is not being used for now.
csThe control structure returned by a previous call to ISOMIP_register_tracer.
ale_sponge_cspA pointer to the control structure for the sponges, if they are in use. Otherwise this may be unassociated.

Definition at line 150 of file ISOMIP_tracer.F90.

150 
151  type(ocean_grid_type), intent(in) :: g !< Grid structure.
152  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
153  logical, intent(in) :: restart !< .true. if the fields have already
154  !! been read from a restart file.
155  type(time_type), target, intent(in) :: day !< Time of the start of the run.
156  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2].
157  type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate
158  !! diagnostic output.
159  type(ocean_obc_type), pointer :: obc !< This open boundary condition type specifies
160  !! whether, where, and what open boundary conditions
161  !! are used. This is not being used for now.
162  type(isomip_tracer_cs), pointer :: cs !< The control structure returned by a previous call
163  !! to ISOMIP_register_tracer.
164  type(ale_sponge_cs), pointer :: ale_sponge_csp !< A pointer to the control structure for
165  !! the sponges, if they are in use. Otherwise this
166  !! may be unassociated.
167 
168  real, allocatable :: temp(:,:,:)
169  real, pointer, dimension(:,:,:) :: &
170  obc_tr1_u => null(), & ! These arrays should be allocated and set to
171  obc_tr1_v => null() ! specify the values of tracer 1 that should come
172  ! in through u- and v- points through the open
173  ! boundary conditions, in the same units as tr.
174  character(len=16) :: name ! A variable's name in a NetCDF file.
175  character(len=72) :: longname ! The long name of that variable.
176  character(len=48) :: units ! The dimensions of the variable.
177  character(len=48) :: flux_units ! The units for tracer fluxes, usually
178  ! kg(tracer) kg(water)-1 m3 s-1 or kg(tracer) s-1.
179  real, pointer :: tr_ptr(:,:,:) => null()
180  real :: h_neglect ! A thickness that is so small it is usually lost
181  ! in roundoff and can be neglected [H ~> m or kg m-2].
182  real :: e(szk_(g)+1), e_top, e_bot, d_tr
183  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m
184  integer :: isdb, iedb, jsdb, jedb
185 
186  if (.not.associated(cs)) return
187  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
188  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
189  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
190  h_neglect = gv%H_subroundoff
191 
192  cs%Time => day
193  cs%diag => diag
194 
195  if (.not.restart) then
196  if (len_trim(cs%tracer_IC_file) >= 1) then
197  ! Read the tracer concentrations from a netcdf file.
198  if (.not.file_exists(cs%tracer_IC_file, g%Domain)) &
199  call mom_error(fatal, "ISOMIP_initialize_tracer: Unable to open "// &
200  cs%tracer_IC_file)
201  do m=1,ntr
202  call query_vardesc(cs%tr_desc(m), name, caller="initialize_ISOMIP_tracer")
203  call mom_read_data(cs%tracer_IC_file, trim(name), cs%tr(:,:,:,m), g%Domain)
204  enddo
205  else
206  do m=1,ntr
207  do k=1,nz ; do j=js,je ; do i=is,ie
208  cs%tr(i,j,k,m) = 0.0
209  enddo ; enddo ; enddo
210  enddo
211  endif
212  endif ! restart
213 
214 ! the following does not work in layer mode yet
215 !! if ( CS%use_sponge ) then
216  ! If sponges are used, this example damps tracers in sponges in the
217  ! northern half of the domain to 1 and tracers in the southern half
218  ! to 0. For any tracers that are not damped in the sponge, the call
219  ! to set_up_sponge_field can simply be omitted.
220 ! if (.not.associated(ALE_sponge_CSp)) &
221 ! call MOM_error(FATAL, "ISOMIP_initialize_tracer: "// &
222 ! "The pointer to ALEsponge_CSp must be associated if SPONGE is defined.")
223 
224 ! allocate(temp(G%isd:G%ied,G%jsd:G%jed,nz))
225 
226 ! do j=js,je ; do i=is,ie
227 ! if (G%geoLonT(i,j) >= 790.0 .AND. G%geoLonT(i,j) <= 800.0) then
228 ! temp(i,j,:) = 1.0
229 ! else
230 ! temp(i,j,:) = 0.0
231 ! endif
232 ! enddo ; enddo
233 
234  ! do m=1,NTR
235 ! do m=1,1
236  ! This is needed to force the compiler not to do a copy in the sponge
237  ! calls. Curses on the designers and implementers of Fortran90.
238 ! tr_ptr => CS%tr(:,:,:,m)
239 ! call set_up_ALE_sponge_field(temp, G, tr_ptr, ALE_sponge_CSp)
240 ! enddo
241 ! deallocate(temp)
242 ! endif
243 

◆ isomip_tracer_column_physics()

subroutine, public isomip_tracer::isomip_tracer_column_physics ( real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h_old,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h_new,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  ea,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  eb,
type(forcing), intent(in)  fluxes,
real, intent(in)  dt,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(isomip_tracer_cs), pointer  CS,
real, intent(in), optional  evap_CFL_limit,
real, intent(in), optional  minimum_forcing_depth 
)

This subroutine applies diapycnal diffusion, including the surface boundary conditions and any other column tracer physics or chemistry to the tracers from this file.

Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in]h_oldLayer thickness before entrainment [H ~> m or kg m-2].
[in]h_newLayer thickness after entrainment [H ~> m or kg m-2].
[in]eaan array to which the amount of fluid entrained
[in]eban array to which the amount of fluid entrained
[in]fluxesA structure containing pointers to thermodynamic and tracer forcing fields. Unused fields have NULL ptrs.
[in]dtThe amount of time covered by this call [T ~> s]
[in]usA dimensional unit scaling type
csThe control structure returned by a previous call to ISOMIP_register_tracer.
[in]evap_cfl_limitLimit on the fraction of the water that can be fluxed out of the top layer in a timestep [nondim]
[in]minimum_forcing_depthThe smallest depth over which fluxes can be applied [H ~> m or kg m-2]

Definition at line 250 of file ISOMIP_tracer.F90.

250  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
251  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure
252  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
253  intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2].
254  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
255  intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2].
256  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
257  intent(in) :: ea !< an array to which the amount of fluid entrained
258  !! from the layer above during this call will be
259  !! added [H ~> m or kg m-2].
260  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
261  intent(in) :: eb !< an array to which the amount of fluid entrained
262  !! from the layer below during this call will be
263  !! added [H ~> m or kg m-2].
264  type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic
265  !! and tracer forcing fields. Unused fields have NULL ptrs.
266  real, intent(in) :: dt !< The amount of time covered by this call [T ~> s]
267  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
268  type(isomip_tracer_cs), pointer :: cs !< The control structure returned by a previous
269  !! call to ISOMIP_register_tracer.
270  real, optional, intent(in) :: evap_cfl_limit !< Limit on the fraction of the water that can
271  !! be fluxed out of the top layer in a timestep [nondim]
272  real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which
273  !! fluxes can be applied [H ~> m or kg m-2]
274 
275 ! The arguments to this subroutine are redundant in that
276 ! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1)
277 
278  ! Local variables
279  real :: b1(szi_(g)) ! b1 and c1 are variables used by the
280  real :: c1(szi_(g),szk_(g)) ! tridiagonal solver.
281  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified
282  real :: melt(szi_(g),szj_(g)) ! melt water (positive for melting, negative for freezing) [R Z T-1 ~> kg m-2 s-1]
283  real :: mmax ! The global maximum melting rate [R Z T-1 ~> kg m-2 s-1]
284  character(len=256) :: mesg ! The text of an error message
285  integer :: i, j, k, is, ie, js, je, nz, m
286  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
287 
288  if (.not.associated(cs)) return
289 
290  melt(:,:) = fluxes%iceshelf_melt(:,:)
291 
292  ! max. melt
293  mmax = maxval(melt(is:ie,js:je))
294  call max_across_pes(mmax)
295  ! write(mesg,*) 'max melt = ', mmax
296  ! call MOM_mesg(mesg, 5)
297  ! dye melt water (m=1), dye = 1 if melt=max(melt)
298  do m=1,ntr
299  do j=js,je ; do i=is,ie
300  if (melt(i,j) > 0.0) then ! melting
301  cs%tr(i,j,1:2,m) = melt(i,j)/mmax ! inject dye in the ML
302  else ! freezing
303  cs%tr(i,j,1:2,m) = 0.0
304  endif
305  enddo ; enddo
306  enddo
307 
308  if (present(evap_cfl_limit) .and. present(minimum_forcing_depth)) then
309  do m=1,ntr
310  do k=1,nz ;do j=js,je ; do i=is,ie
311  h_work(i,j,k) = h_old(i,j,k)
312  enddo ; enddo ; enddo
313  call applytracerboundaryfluxesinout(g, gv, cs%tr(:,:,:,m), dt, fluxes, h_work, &
314  evap_cfl_limit, minimum_forcing_depth)
315  call tracer_vertdiff(h_work, ea, eb, dt, cs%tr(:,:,:,m), g, gv)
316  enddo
317  else
318  do m=1,ntr
319  call tracer_vertdiff(h_old, ea, eb, dt, cs%tr(:,:,:,m), g, gv)
320  enddo
321  endif
322 

◆ isomip_tracer_end()

subroutine, public isomip_tracer::isomip_tracer_end ( type(isomip_tracer_cs), pointer  CS)

Deallocate any memory used by the ISOMIP tracer package.

Parameters
csThe control structure returned by a previous call to ISOMIP_register_tracer.

Definition at line 360 of file ISOMIP_tracer.F90.

360  type(isomip_tracer_cs), pointer :: cs !< The control structure returned by a previous
361  !! call to ISOMIP_register_tracer.
362  integer :: m
363 
364  if (associated(cs)) then
365  if (associated(cs%tr)) deallocate(cs%tr)
366  deallocate(cs)
367  endif

◆ isomip_tracer_surface_state()

subroutine, public isomip_tracer::isomip_tracer_surface_state ( type(surface), intent(inout)  sfc_state,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
type(ocean_grid_type), intent(in)  G,
type(isomip_tracer_cs), pointer  CS 
)

This subroutine extracts the surface fields from this tracer package that are to be shared with the atmosphere in coupled configurations. This particular tracer package does not report anything back to the coupler.

Parameters
[in]gThe ocean's grid structure.
[in,out]sfc_stateA structure containing fields that describe the surface state of the ocean.
[in]hLayer thickness [H ~> m or kg m-2].
csThe control structure returned by a previous call to ISOMIP_register_tracer.

Definition at line 329 of file ISOMIP_tracer.F90.

329  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
330  type(surface), intent(inout) :: sfc_state !< A structure containing fields that
331  !! describe the surface state of the ocean.
332  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
333  intent(in) :: h !< Layer thickness [H ~> m or kg m-2].
334  type(isomip_tracer_cs), pointer :: cs !< The control structure returned by a previous
335  !! call to ISOMIP_register_tracer.
336 
337  ! This particular tracer package does not report anything back to the coupler.
338  ! The code that is here is just a rough guide for packages that would.
339 
340  integer :: m, is, ie, js, je, isd, ied, jsd, jed
341  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
342  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
343 
344  if (.not.associated(cs)) return
345 
346  if (cs%coupled_tracers) then
347  do m=1,ntr
348  ! This call loads the surface values into the appropriate array in the
349  ! coupler-type structure.
350  call coupler_type_set_data(cs%tr(:,:,1,m), cs%ind_tr(m), ind_csurf, &
351  sfc_state%tr_fields, idim=(/isd, is, ie, ied/), &
352  jdim=(/jsd, js, je, jed/) )
353  enddo
354  endif
355 

◆ register_isomip_tracer()

logical function, public isomip_tracer::register_isomip_tracer ( type(hor_index_type), intent(in)  HI,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
type(isomip_tracer_cs), pointer  CS,
type(tracer_registry_type), pointer  tr_Reg,
type(mom_restart_cs), pointer  restart_CS 
)

This subroutine is used to register tracer fields.

Parameters
[in]hiA horizontal index type structure.
[in]gvThe ocean's vertical grid structure.
[in]param_fileA structure indicating the open file to parse for model parameter values.
csA pointer that is set to point to the control structure for this module (in/out).
tr_regA pointer to the tracer registry.
restart_csA pointer to the restart control structure.

Definition at line 69 of file ISOMIP_tracer.F90.

69  type(hor_index_type), intent(in) :: hi !<A horizontal index type structure.
70  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
71  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
72  !! to parse for model parameter values.
73  type(isomip_tracer_cs), pointer :: cs !<A pointer that is set to point to the control
74  !! structure for this module (in/out).
75  type(tracer_registry_type), pointer :: tr_reg !<A pointer to the tracer registry.
76  type(mom_restart_cs), pointer :: restart_cs !<A pointer to the restart control structure.
77 
78  character(len=80) :: name, longname
79 ! This include declares and sets the variable "version".
80 #include "version_variable.h"
81  character(len=40) :: mdl = "ISOMIP_tracer" ! This module's name.
82  character(len=200) :: inputdir
83  character(len=48) :: flux_units ! The units for tracer fluxes, usually
84  ! kg(tracer) kg(water)-1 m3 s-1 or kg(tracer) s-1.
85  real, pointer :: tr_ptr(:,:,:) => null()
86  logical :: register_isomip_tracer
87  integer :: isd, ied, jsd, jed, nz, m
88  isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
89 
90  if (associated(cs)) then
91  call mom_error(warning, "ISOMIP_register_tracer called with an "// &
92  "associated control structure.")
93  return
94  endif
95  allocate(cs)
96 
97  ! Read all relevant parameters and write them to the model log.
98  call log_version(param_file, mdl, version, "")
99  call get_param(param_file, mdl, "ISOMIP_TRACER_IC_FILE", cs%tracer_IC_file, &
100  "The name of a file from which to read the initial "//&
101  "conditions for the ISOMIP tracers, or blank to initialize "//&
102  "them internally.", default=" ")
103  if (len_trim(cs%tracer_IC_file) >= 1) then
104  call get_param(param_file, mdl, "INPUTDIR", inputdir, default=".")
105  inputdir = slasher(inputdir)
106  cs%tracer_IC_file = trim(inputdir)//trim(cs%tracer_IC_file)
107  call log_param(param_file, mdl, "INPUTDIR/ISOMIP_TRACER_IC_FILE", &
108  cs%tracer_IC_file)
109  endif
110  call get_param(param_file, mdl, "SPONGE", cs%use_sponge, &
111  "If true, sponges may be applied anywhere in the domain. "//&
112  "The exact location and properties of those sponges are "//&
113  "specified from MOM_initialization.F90.", default=.false.)
114 
115  allocate(cs%tr(isd:ied,jsd:jed,nz,ntr)) ; cs%tr(:,:,:,:) = 0.0
116 
117  do m=1,ntr
118  if (m < 10) then ; write(name,'("tr_D",I1.1)') m
119  else ; write(name,'("tr_D",I2.2)') m ; endif
120  write(longname,'("Concentration of ISOMIP Tracer ",I2.2)') m
121  cs%tr_desc(m) = var_desc(name, units="kg kg-1", longname=longname, caller=mdl)
122  if (gv%Boussinesq) then ; flux_units = "kg kg-1 m3 s-1"
123  else ; flux_units = "kg s-1" ; endif
124 
125  ! This is needed to force the compiler not to do a copy in the registration
126  ! calls. Curses on the designers and implementers of Fortran90.
127  tr_ptr => cs%tr(:,:,:,m)
128  ! Register the tracer for horizontal advection, diffusion, and restarts.
129  call register_tracer(tr_ptr, tr_reg, param_file, hi, gv, &
130  name=name, longname=longname, units="kg kg-1", &
131  registry_diags=.true., flux_units=flux_units, &
132  restart_cs=restart_cs)
133 
134  ! Set coupled_tracers to be true (hard-coded above) to provide the surface
135  ! values to the coupler (if any). This is meta-code and its arguments will
136  ! currently (deliberately) give fatal errors if it is used.
137  if (cs%coupled_tracers) &
138  cs%ind_tr(m) = aof_set_coupler_flux(trim(name)//'_flux', &
139  flux_type=' ', implementation=' ', caller="register_ISOMIP_tracer")
140  enddo
141 
142  cs%tr_Reg => tr_reg
143  register_isomip_tracer = .true.