MOM6
boundary_impulse_tracer Module Reference

Detailed Description

Implements a boundary impulse response tracer to calculate Green's functions.

Impulse Response Tracer and Transit Time Distributions

Transit time distributions (TTD) are the Green's function solution of the passive tracer equation between the oceanic surface and interior. The name derives from the idea that the 'age' (e.g. time since last contact with the atmosphere) of a water parcel is best characterized as a distribution of ages because water parcels leaving the surface arrive at a particular interior point at different times. The more commonly used ideal age tracer is the first moment of the TTD, equivalently referred to as the mean age.

A boundary impulse response (BIR) is a passive tracer whose surface boundary condition is a rectangle function with width \(\Delta t\). In the case of unsteady flow, multiple BIRs, initiated at different times in the model can be used to infer the transit time distribution or Green's function between the oceanic surface and interior. In the case of steady or cyclostationary flow, a single BIR is sufficient.

In the References section, both the theoretical discussion of TTDs and BIRs are listed along with modeling studies which have this used framework in scientific investigations

parameters

-DO_BOUNDARY_IMPULSE_TRACER: Enables the boundary impulse tracer model -IMPULSE_SOURCE_TIME: Length of time that the surface layer acts as a source of the BIR tracer

References

and BIR Theory

-Holzer, M., and T.M. Hall, 2000: Transit-time and tracer-age distributions in geophysical flows. J. Atmos. Sci., 57, 3539-3558, doi:10.1175/1520-0469(2000)057<3539:TTATAD>2.0.CO;2. -T.W.N. Haine, H. Zhang, D.W. Waugh, M. Holzer, On transit-time distributions in unsteady circulation models, Ocean Modelling, Volume 21, Issues 1–2, 2008, Pages 35-45, ISSN 1463-5003 http://dx.doi.org/10.1016/j.ocemod.2007.11.004.

Modelling applications

-Peacock, S., and M. Maltrud (2006), Transit-time distributions in a global ocean model, J. Phys. Oceanogr., 36(3), 474–495, doi:10.1175/JPO2860.1. -Maltrud, M., Bryan, F. & Peacock, Boundary impulse response functions in a century-long eddying global ocean simulation, S. Environ Fluid Mech (2010) 10: 275. doi:10.1007/s10652-009-9154-3

Data Types

type  boundary_impulse_tracer_cs
 
type  p3d
 

Functions/Subroutines

logical function, public register_boundary_impulse_tracer (HI, GV, param_file, CS, tr_Reg, restart_CS)
 Read in runtime options and add boundary impulse tracer to tracer registry. More...
 
subroutine, public initialize_boundary_impulse_tracer (restart, day, G, GV, h, diag, OBC, CS, sponge_CSp, diag_to_Z_CSp, tv)
 Initialize tracer from restart or set to 1 at surface to initialize. More...
 
subroutine, public boundary_impulse_tracer_column_physics (h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, tv, debug, evap_CFL_limit, minimum_forcing_depth)
 
integer function, public boundary_impulse_stock (h, stocks, G, GV, CS, names, units, stock_index)
 Calculate total inventory of tracer. More...
 
subroutine, public boundary_impulse_tracer_surface_state (state, h, G, CS)
 Called if returned if coupler needs to know about tracer, currently unused. More...
 
subroutine, public boundary_impulse_tracer_end (CS)
 

Variables

integer, parameter ntr_max = 1
 

Function/Subroutine Documentation

◆ boundary_impulse_stock()

integer function, public boundary_impulse_tracer::boundary_impulse_stock ( real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h,
real, dimension(:), intent(out)  stocks,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(boundary_impulse_tracer_cs), intent(in), pointer  CS,
character(len=*), dimension(:), intent(out)  names,
character(len=*), dimension(:), intent(out)  units,
integer, intent(in), optional  stock_index 
)

Calculate total inventory of tracer.

Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in]hLayer thicknesses, in H (usually m or kg m-2)

Definition at line 395 of file boundary_impulse_tracer.F90.

References mom_io::query_vardesc().

395  type(ocean_grid_type), intent(in ) :: g !< The ocean's grid structure
396  type(verticalgrid_type), intent(in ) :: gv !< The ocean's vertical grid structure
397  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in ) :: h !< Layer thicknesses, in H (usually m or kg m-2)
398  real, dimension(:), intent( out) :: stocks
399  type(boundary_impulse_tracer_cs), pointer, intent(in ) :: cs
400  character(len=*), dimension(:), intent( out) :: names
401  character(len=*), dimension(:), intent( out) :: units
402  integer, optional, intent(in ) :: stock_index
403 ! This function calculates the mass-weighted integral of all tracer stocks,
404 ! returning the number of stocks it has calculated. If the stock_index
405 ! is present, only the stock corresponding to that coded index is returned.
406 
407 ! Arguments: h - Layer thickness, in m or kg m-2.
408 ! (out) stocks - the mass-weighted integrated amount of each tracer,
409 ! in kg times concentration units.
410 ! (in) G - The ocean's grid structure.
411 ! (in) GV - The ocean's vertical grid structure.
412 ! (in) CS - The control structure returned by a previous call to
413 ! register_boundary_impulse_tracer.
414 ! (out) names - the names of the stocks calculated.
415 ! (out) units - the units of the stocks calculated.
416 ! (in,opt) stock_index - the coded index of a specific stock being sought.
417 ! Return value: the number of stocks calculated here.
418  integer :: boundary_impulse_stock
419  integer :: i, j, k, is, ie, js, je, nz, m
420  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
421 
422  boundary_impulse_stock = 0
423  if (.not.associated(cs)) return
424  if (cs%ntr < 1) return
425 
426  if (present(stock_index)) then ; if (stock_index > 0) then
427  ! Check whether this stock is available from this routine.
428 
429  ! No stocks from this routine are being checked yet. Return 0.
430  return
431  endif ; endif
432 
433  do m=1,1
434  call query_vardesc(cs%tr_desc(m), name=names(m), units=units(m), caller="boundary_impulse_stock")
435  units(m) = trim(units(m))//" kg"
436  stocks(m) = 0.0
437  do k=1,nz ; do j=js,je ; do i=is,ie
438  stocks(m) = stocks(m) + cs%tr(i,j,k,m) * &
439  (g%mask2dT(i,j) * g%areaT(i,j) * h(i,j,k))
440  enddo ; enddo ; enddo
441  stocks(m) = gv%H_to_kg_m2 * stocks(m)
442  enddo
443 
444  boundary_impulse_stock = cs%ntr
445 
Here is the call graph for this function:

◆ boundary_impulse_tracer_column_physics()

subroutine, public boundary_impulse_tracer::boundary_impulse_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(boundary_impulse_tracer_cs), intent(inout), pointer  CS,
type(thermo_var_ptrs), intent(in)  tv,
logical, intent(in)  debug,
real, intent(in), optional  evap_CFL_limit,
real, intent(in), optional  minimum_forcing_depth 
)
Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in]dtThe amount of time covered by this call, in s
[in]tvA structure pointing to various thermodynamic variables

Definition at line 283 of file boundary_impulse_tracer.F90.

References mom_tracer_diabatic::applytracerboundaryfluxesinout(), and mom_tracer_diabatic::tracer_vertdiff().

283  type(ocean_grid_type), intent(in ) :: g !< The ocean's grid structure
284  type(verticalgrid_type), intent(in ) :: gv !< The ocean's vertical grid structure
285  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in ) :: h_old, h_new, ea, eb
286  type(forcing), intent(in ) :: fluxes
287  real, intent(in ) :: dt !< The amount of time covered by this call, in s
288  type(boundary_impulse_tracer_cs), pointer, intent(inout) :: cs
289  type(thermo_var_ptrs), intent(in ) :: tv !< A structure pointing to various thermodynamic variables
290  logical, intent(in ) :: debug
291  real, optional, intent(in ) :: evap_cfl_limit
292  real, optional, intent(in ) :: minimum_forcing_depth
293 
294 ! This subroutine applies diapycnal diffusion and any other column
295 ! tracer physics or chemistry to the tracers from this file.
296 ! This is a simple example of a set of advected passive tracers.
297 
298 ! Arguments: h_old - Layer thickness before entrainment, in m or kg m-2.
299 ! (in) h_new - Layer thickness after entrainment, in m or kg m-2.
300 ! (in) ea - an array to which the amount of fluid entrained
301 ! from the layer above during this call will be
302 ! added, in m or kg m-2.
303 ! (in) eb - an array to which the amount of fluid entrained
304 ! from the layer below during this call will be
305 ! added, in m or kg m-2.
306 ! (in) fluxes - A structure containing pointers to any possible
307 ! forcing fields. Unused fields have NULL ptrs.
308 ! (in) dt - The amount of time covered by this call, in s.
309 ! (in) G - The ocean's grid structure.
310 ! (in) GV - The ocean's vertical grid structure.
311 ! (in) CS - The control structure returned by a previous call to
312 ! register_boundary_impulse_tracer.
313 ! (in) tv - Thermodynamic structure with T and S
314 ! (in) evap_CFL_limit - Limits how much water can be fluxed out of the top layer
315 ! Stored previously in diabatic CS.
316 ! (in) minimum_forcing_depth - The smallest depth over which fluxes can be applied
317 ! Stored previously in diabatic CS.
318 ! (in) debug - Calculates checksums
319 !
320 ! The arguments to this subroutine are redundant in that
321 ! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1]
322 
323  real :: isecs_per_year = 1.0 / (365.0*86400.0)
324  real :: year, h_total, scale, htot, ih_limit
325  integer :: secs, days
326  integer :: i, j, k, is, ie, js, je, nz, m, k_max
327  real, allocatable :: local_tr(:,:,:)
328  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified
329 
330  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
331 
332  if (.not.associated(cs)) return
333  if (cs%ntr < 1) return
334 
335  ! This uses applyTracerBoundaryFluxesInOut, usually in ALE mode
336  if (present(evap_cfl_limit) .and. present(minimum_forcing_depth)) then
337  do k=1,nz ;do j=js,je ; do i=is,ie
338  h_work(i,j,k) = h_old(i,j,k)
339  enddo ; enddo ; enddo;
340  call applytracerboundaryfluxesinout(g, gv, cs%tr(:,:,:,1), dt, fluxes, h_work, &
341  evap_cfl_limit, minimum_forcing_depth)
342  call tracer_vertdiff(h_work, ea, eb, dt, cs%tr(:,:,:,1), g, gv)
343  else
344  call tracer_vertdiff(h_old, ea, eb, dt, cs%tr(:,:,:,1), g, gv)
345  endif
346 
347  ! Set surface conditions
348  do m=1,1
349  if(cs%remaining_source_time>0.0) then
350  do k=1,cs%nkml ; do j=js,je ; do i=is,ie
351  cs%tr(i,j,k,m) = 1.0
352  enddo ; enddo ; enddo
353  cs%remaining_source_time = cs%remaining_source_time-dt
354  else
355  do k=1,cs%nkml ; do j=js,je ; do i=is,ie
356  cs%tr(i,j,k,m) = 0.0
357  enddo ; enddo ; enddo
358  endif
359 
360  enddo
361 
362  allocate(local_tr(g%isd:g%ied,g%jsd:g%jed,nz))
363  do m=1,1
364  if (cs%id_tracer(m)>0) then
365  if (cs%mask_tracers) then
366  do k=1,nz ; do j=js,je ; do i=is,ie
367  if (h_new(i,j,k) < 1.1*gv%Angstrom) then
368  local_tr(i,j,k) = cs%land_val(m)
369  else
370  local_tr(i,j,k) = cs%tr(i,j,k,m)
371  endif
372  enddo ; enddo ; enddo
373  else
374  do k=1,nz ; do j=js,je ; do i=is,ie
375  local_tr(i,j,k) = cs%tr(i,j,k,m)
376  enddo ; enddo ; enddo
377  endif ! CS%mask_tracers
378  call post_data(cs%id_tracer(m),local_tr,cs%diag)
379  endif ! CS%id_tracer(m)>0
380  if (cs%id_tr_adx(m)>0) &
381  call post_data(cs%id_tr_adx(m),cs%tr_adx(m)%p(:,:,:),cs%diag)
382  if (cs%id_tr_ady(m)>0) &
383  call post_data(cs%id_tr_ady(m),cs%tr_ady(m)%p(:,:,:),cs%diag)
384  if (cs%id_tr_dfx(m)>0) &
385  call post_data(cs%id_tr_dfx(m),cs%tr_dfx(m)%p(:,:,:),cs%diag)
386  if (cs%id_tr_dfy(m)>0) &
387  call post_data(cs%id_tr_dfy(m),cs%tr_dfy(m)%p(:,:,:),cs%diag)
388  enddo
389  deallocate(local_tr)
390 
Here is the call graph for this function:

◆ boundary_impulse_tracer_end()

subroutine, public boundary_impulse_tracer::boundary_impulse_tracer_end ( type(boundary_impulse_tracer_cs), pointer  CS)

Definition at line 480 of file boundary_impulse_tracer.F90.

480  type(boundary_impulse_tracer_cs), pointer :: cs
481  integer :: m
482 
483  if (associated(cs)) then
484  if (associated(cs%tr)) deallocate(cs%tr)
485  do m=1,cs%ntr
486  if (associated(cs%tr_adx(m)%p)) deallocate(cs%tr_adx(m)%p)
487  if (associated(cs%tr_ady(m)%p)) deallocate(cs%tr_ady(m)%p)
488  if (associated(cs%tr_dfx(m)%p)) deallocate(cs%tr_dfx(m)%p)
489  if (associated(cs%tr_dfy(m)%p)) deallocate(cs%tr_dfy(m)%p)
490  enddo
491 
492  deallocate(cs)
493  endif

◆ boundary_impulse_tracer_surface_state()

subroutine, public boundary_impulse_tracer::boundary_impulse_tracer_surface_state ( type(surface), intent(inout)  state,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h,
type(ocean_grid_type), intent(in)  G,
type(boundary_impulse_tracer_cs), intent(in), pointer  CS 
)

Called if returned if coupler needs to know about tracer, currently unused.

Parameters
[in]gThe ocean's grid structure
[in]hLayer thicknesses, in H (usually m or kg m-2)

Definition at line 450 of file boundary_impulse_tracer.F90.

References coupler_util::set_coupler_values().

450  type(ocean_grid_type), intent(in ) :: g !< The ocean's grid structure
451  type(surface), intent(inout) :: state
452  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in ) :: h !< Layer thicknesses, in H (usually m or kg m-2)
453  type(boundary_impulse_tracer_cs), pointer,intent(in ) :: cs
454 ! This particular tracer package does not report anything back to the coupler.
455 ! The code that is here is just a rough guide for packages that would.
456 ! Arguments: state - A structure containing fields that describe the
457 ! surface state of the ocean.
458 ! (in) h - Layer thickness, in m or kg m-2.
459 ! (in) G - The ocean's grid structure.
460 ! (in) CS - The control structure returned by a previous call to
461 ! register_boundary_impulse_tracer.
462  integer :: m, is, ie, js, je
463  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
464 
465  if (.not.associated(cs)) return
466 
467  if (cs%coupled_tracers) then
468  do m=1,cs%ntr
469  ! This call loads the surface vlues into the appropriate array in the
470  ! coupler-type structure.
471  call set_coupler_values(cs%tr(:,:,1,m), state%tr_fields, cs%ind_tr(m), &
472  ind_csurf, is, ie, js, je)
473  enddo
474  endif
475 
Here is the call graph for this function:

◆ initialize_boundary_impulse_tracer()

subroutine, public boundary_impulse_tracer::initialize_boundary_impulse_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(szi_(g),szj_(g),szk_(g)), intent(in)  h,
type(diag_ctrl), intent(in), target  diag,
type(ocean_obc_type), intent(inout), pointer  OBC,
type(boundary_impulse_tracer_cs), intent(inout), pointer  CS,
type(sponge_cs), intent(inout), pointer  sponge_CSp,
type(diag_to_z_cs), intent(inout), pointer  diag_to_Z_CSp,
type(thermo_var_ptrs), intent(in)  tv 
)

Initialize tracer from restart or set to 1 at surface to initialize.

Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in]hLayer thicknesses, in H (usually m or kg m-2)
[in]tvA structure pointing to various thermodynamic variables

Definition at line 175 of file boundary_impulse_tracer.F90.

References mom_tracer_registry::add_tracer_diagnostics(), mom_io::query_vardesc(), and mom_diag_to_z::register_z_tracer().

175  logical, intent(in ) :: restart
176  type(time_type), target, intent(in ) :: day
177  type(ocean_grid_type), intent(in ) :: g !< The ocean's grid structure
178  type(verticalgrid_type), intent(in ) :: gv !< The ocean's vertical grid structure
179  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in ) :: h !< Layer thicknesses, in H (usually m or kg m-2)
180  type(diag_ctrl), target, intent(in ) :: diag
181  type(ocean_obc_type), pointer, intent(inout) :: obc
182  type(boundary_impulse_tracer_cs), pointer,intent(inout) :: cs
183  type(sponge_cs), pointer, intent(inout) :: sponge_csp
184  type(diag_to_z_cs), pointer, intent(inout) :: diag_to_z_csp
185  type(thermo_var_ptrs), intent(in ) :: tv !< A structure pointing to various thermodynamic variables
186 ! This subroutine initializes the CS%ntr tracer fields in tr(:,:,:,:)
187 ! and it sets up the tracer output.
188 
189 ! Arguments: restart - .true. if the fields have already been read from
190 ! a restart file.
191 ! (in) day - Time of the start of the run.
192 ! (in) G - The ocean's grid structure.
193 ! (in) GV - The ocean's vertical grid structure.
194 ! (in) h - Layer thickness, in m or kg m-2.
195 ! (in) diag - A structure that is used to regulate diagnostic output.
196 ! (in) OBC - This open boundary condition type specifies whether, where,
197 ! and what open boundary conditions are used.
198 ! (in/out) CS - The control structure returned by a previous call to
199 ! register_boundary_impulse_tracer.
200 ! (in/out) sponge_CSp - A pointer to the control structure for the sponges, if
201 ! they are in use. Otherwise this may be unassociated.
202 ! (in/out) diag_to_Z_Csp - A pointer to the control structure for diagnostics
203 ! in depth space.
204  character(len=16) :: name ! A variable's name in a NetCDF file.
205  character(len=72) :: longname ! The long name of that variable.
206  character(len=48) :: units ! The dimensions of the variable.
207  character(len=48) :: flux_units ! The units for age tracer fluxes, either
208  ! years m3 s-1 or years kg s-1.
209  logical :: ok
210  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m
211  integer :: isdb, iedb, jsdb, jedb
212 
213  if (.not.associated(cs)) return
214  if (cs%ntr < 1) return
215  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
216  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
217  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
218 
219  cs%Time => day
220  cs%diag => diag
221  name = "boundary_impulse"
222 
223  do m=1,cs%ntr
224  call query_vardesc(cs%tr_desc(m), name=name, caller="initialize_boundary_impulse_tracer")
225  if ((.not.restart) .or. (.not. &
226  query_initialized(cs%tr(:,:,:,m), name, cs%restart_CSp))) then
227  do k=1,cs%nkml ; do j=jsd,jed ; do i=isd,ied
228  cs%tr(i,j,k,m) = 1.0
229  enddo ; enddo ; enddo
230  endif
231  enddo ! Tracer loop
232 
233  if (associated(obc)) then
234  ! All tracers but the first have 0 concentration in their inflows. As this
235  ! is the default value, the following calls are unnecessary.
236  ! do m=1,CS%ntr
237  ! call add_tracer_OBC_values(trim(CS%tr_desc(m)%name), CS%tr_Reg, 0.0)
238  ! enddo
239  endif
240 
241  ! This needs to be changed if the units of tracer are changed above.
242  if (gv%Boussinesq) then ; flux_units = "g salt/(m^2 s)"
243  else ; flux_units = "g salt/(m^2 s)" ; endif
244 
245  do m=1,cs%ntr
246  ! Register the tracer for the restart file.
247  call query_vardesc(cs%tr_desc(m), name, units=units, longname=longname, &
248  caller="initialize_boundary_impulse_tracer")
249  cs%id_tracer(m) = register_diag_field("ocean_model", trim(name), cs%diag%axesTL, &
250  day, trim(longname) , trim(units))
251  cs%id_tr_adx(m) = register_diag_field("ocean_model", trim(name)//"_adx", &
252  cs%diag%axesCuL, day, trim(longname)//" advective zonal flux" , &
253  trim(flux_units))
254  cs%id_tr_ady(m) = register_diag_field("ocean_model", trim(name)//"_ady", &
255  cs%diag%axesCvL, day, trim(longname)//" advective meridional flux" , &
256  trim(flux_units))
257  cs%id_tr_dfx(m) = register_diag_field("ocean_model", trim(name)//"_dfx", &
258  cs%diag%axesCuL, day, trim(longname)//" diffusive zonal flux" , &
259  trim(flux_units))
260  cs%id_tr_dfy(m) = register_diag_field("ocean_model", trim(name)//"_dfy", &
261  cs%diag%axesCvL, day, trim(longname)//" diffusive zonal flux" , &
262  trim(flux_units))
263  if (cs%id_tr_adx(m) > 0) call safe_alloc_ptr(cs%tr_adx(m)%p,isdb,iedb,jsd,jed,nz)
264  if (cs%id_tr_ady(m) > 0) call safe_alloc_ptr(cs%tr_ady(m)%p,isd,ied,jsdb,jedb,nz)
265  if (cs%id_tr_dfx(m) > 0) call safe_alloc_ptr(cs%tr_dfx(m)%p,isdb,iedb,jsd,jed,nz)
266  if (cs%id_tr_dfy(m) > 0) call safe_alloc_ptr(cs%tr_dfy(m)%p,isd,ied,jsdb,jedb,nz)
267 
268 ! Register the tracer for horizontal advection & diffusion.
269  if ((cs%id_tr_adx(m) > 0) .or. (cs%id_tr_ady(m) > 0) .or. &
270  (cs%id_tr_dfx(m) > 0) .or. (cs%id_tr_dfy(m) > 0)) &
271  call add_tracer_diagnostics(name, cs%tr_Reg, cs%tr_adx(m)%p, &
272  cs%tr_ady(m)%p,cs%tr_dfx(m)%p,cs%tr_dfy(m)%p)
273 
274  call register_z_tracer(cs%tr(:,:,:,m), trim(name), longname, units, &
275  day, g, diag_to_z_csp)
276  enddo
277 
Here is the call graph for this function:

◆ register_boundary_impulse_tracer()

logical function, public boundary_impulse_tracer::register_boundary_impulse_tracer ( type(hor_index_type), intent(in)  HI,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
type(boundary_impulse_tracer_cs), intent(inout), pointer  CS,
type(tracer_registry_type), intent(inout), pointer  tr_Reg,
type(mom_restart_cs), intent(inout), pointer  restart_CS 
)

Read in runtime options and add boundary impulse tracer to tracer registry.

Parameters
[in]gvThe ocean's vertical grid structure
[in]param_fileA structure to parse for run-time parameters

Definition at line 84 of file boundary_impulse_tracer.F90.

References atmos_ocean_fluxes_mod::aof_set_coupler_flux(), mom_error_handler::mom_error(), ntr_max, mom_io::query_vardesc(), and mom_io::var_desc().

84  type(hor_index_type), intent(in ) :: hi
85  type(verticalgrid_type), intent(in ) :: gv !< The ocean's vertical grid structure
86  type(param_file_type), intent(in ) :: param_file !< A structure to parse for run-time parameters
87  type(boundary_impulse_tracer_cs), pointer, intent(inout) :: cs
88  type(tracer_registry_type), pointer, intent(inout) :: tr_reg
89  type(mom_restart_cs), pointer, intent(inout) :: restart_cs
90 ! This subroutine is used to register tracer fields and subroutines
91 ! to be used with MOM.
92 ! Arguments: HI - A horizontal index type structure.
93 ! (in) GV - The ocean's vertical grid structure.
94 ! (in) param_file - A structure indicating the open file to parse for
95 ! model parameter values.
96 ! (in/out) CS - A pointer that is set to point to the control structure
97 ! for this module
98 ! (in/out) tr_Reg - A pointer that is set to point to the control structure
99 ! for the tracer advection and diffusion module.
100 ! (in) restart_CS - A pointer to the restart control structure.
101 
102 ! This include declares and sets the variable "version".
103 #include "version_variable.h"
104  character(len=40) :: mdl = "boundary_impulse_tracer" ! This module's name.
105  character(len=200) :: inputdir ! The directory where the input files are.
106  character(len=48) :: var_name ! The variable's name.
107  character(len=3) :: name_tag ! String for creating identifying boundary_impulse
108  real, pointer :: tr_ptr(:,:,:) => null()
109  real, pointer :: rem_time_ptr => null()
110  logical :: register_boundary_impulse_tracer
111  integer :: isd, ied, jsd, jed, nz, m, i, j
112  isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
113 
114  if (associated(cs)) then
115  call mom_error(warning, "register_boundary_impulse_tracer called with an "// &
116  "associated control structure.")
117  return
118  endif
119  allocate(cs)
120 
121  ! Read all relevant parameters and write them to the model log.
122  call log_version(param_file, mdl, version, "")
123  call get_param(param_file, mdl, "IMPULSE_SOURCE_TIME", cs%remaining_source_time, &
124  "Length of time for the boundary tracer to be injected\n"//&
125  "into the mixed layer. After this time has elapsed, the\n"//&
126  "surface becomes a sink for the boundary impulse tracer.", &
127  default=31536000.0)
128  call get_param(param_file, mdl, "TRACERS_MAY_REINIT", cs%tracers_may_reinit, &
129  "If true, tracers may go through the initialization code \n"//&
130  "if they are not found in the restart files. Otherwise \n"//&
131  "it is a fatal error if the tracers are not found in the \n"//&
132  "restart files of a restarted run.", default=.false.)
133  cs%ntr = ntr_max
134  allocate(cs%tr(isd:ied,jsd:jed,nz,cs%ntr)) ; cs%tr(:,:,:,:) = 0.0
135 
136  cs%nkml = max(gv%nkml,1)
137 
138  do m=1,cs%ntr
139  ! This is needed to force the compiler not to do a copy in the registration
140  ! calls. Curses on the designers and implementers of Fortran90.
141  cs%tr_desc(m) = var_desc(trim("boundary_impulse"), "kg", &
142  "Boundary impulse tracer", caller=mdl)
143  tr_ptr => cs%tr(:,:,:,m)
144  call query_vardesc(cs%tr_desc(m), name=var_name, caller="register_boundary_impulse_tracer")
145  ! Register the tracer for the restart file.
146  call register_restart_field(tr_ptr, cs%tr_desc(m), &
147  .not. cs%tracers_may_reinit, restart_cs)
148  ! Register the tracer for horizontal advection & diffusion.
149  call register_tracer(tr_ptr, cs%tr_desc(m), param_file, hi, gv, tr_reg, &
150  tr_desc_ptr=cs%tr_desc(m))
151 
152  ! Set coupled_tracers to be true (hard-coded above) to provide the surface
153  ! values to the coupler (if any). This is meta-code and its arguments will
154  ! currently (deliberately) give fatal errors if it is used.
155  if (cs%coupled_tracers) &
156  cs%ind_tr(m) = aof_set_coupler_flux(trim(var_name)//'_flux', &
157  flux_type=' ', implementation=' ', caller="register_boundary_impulse_tracer")
158  enddo
159  ! Register remaining source time as a restart field
160  rem_time_ptr => cs%remaining_source_time
161  call register_restart_field(rem_time_ptr, &
162  var_desc(trim("bir_remain_time"), "s", "Remaining time to apply BIR source", &
163  hor_grid = "1", z_grid = "1", caller=mdl), &
164  .not. cs%tracers_may_reinit, restart_cs)
165 
166  cs%tr_Reg => tr_reg
167  cs%restart_CSp => restart_cs
168  register_boundary_impulse_tracer = .true.
169 
Here is the call graph for this function:

Variable Documentation

◆ ntr_max

integer, parameter boundary_impulse_tracer::ntr_max = 1
private

Definition at line 37 of file boundary_impulse_tracer.F90.

Referenced by register_boundary_impulse_tracer().

37 integer, parameter :: ntr_max = 1