40 implicit none ;
private 42 #include <MOM_memory.h> 49 integer,
parameter ::
ntr = 1
52 real,
dimension(:,:,:),
pointer :: p => null()
57 logical :: coupled_tracers = .false.
59 character(len = 200) :: tracer_ic_file
61 type(time_type),
pointer :: time
63 real,
pointer :: tr(:,:,:,:) => null()
65 real,
pointer :: tr_aux(:,:,:,:) => null()
67 type(
p3d),
dimension(NTR) :: &
68 tr_adx, &!< Tracer zonal advective fluxes in g m-3 m3 s-1.
69 tr_ady, &!< Tracer meridional advective fluxes in g m-3 m3 s-1.
70 tr_dfx, &!< Tracer zonal diffusive fluxes in g m-3 m3 s-1.
72 real :: land_val(
ntr) = -1.0
73 logical :: mask_tracers
76 integer,
dimension(NTR) :: ind_tr
82 integer,
dimension(NTR) :: id_tracer = -1, id_tr_adx = -1, id_tr_ady = -1
83 integer,
dimension(NTR) :: id_tr_dfx = -1, id_tr_dfy = -1
101 character(len=80) :: name, longname
103 #include "version_variable.h" 104 character(len=40) :: mdl =
"ISOMIP_tracer" 105 character(len=200) :: inputdir
106 real,
pointer :: tr_ptr(:,:,:) => null()
107 logical :: register_ISOMIP_tracer
108 integer :: isd, ied, jsd, jed, nz, m
109 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
111 if (
associated(cs))
then 112 call mom_error(warning,
"ISOMIP_register_tracer called with an "// &
113 "associated control structure.")
120 call get_param(param_file, mdl,
"ISOMIP_TRACER_IC_FILE", cs%tracer_IC_file, &
121 "The name of a file from which to read the initial \n"//&
122 "conditions for the ISOMIP tracers, or blank to initialize \n"//&
123 "them internally.", default=
" ")
124 if (len_trim(cs%tracer_IC_file) >= 1)
then 125 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
126 inputdir = slasher(inputdir)
127 cs%tracer_IC_file = trim(inputdir)//trim(cs%tracer_IC_file)
128 call log_param(param_file, mdl,
"INPUTDIR/ISOMIP_TRACER_IC_FILE", &
131 call get_param(param_file, mdl,
"SPONGE", cs%use_sponge, &
132 "If true, sponges may be applied anywhere in the domain. \n"//&
133 "The exact location and properties of those sponges are \n"//&
134 "specified from MOM_initialization.F90.", default=.false.)
136 allocate(cs%tr(isd:ied,jsd:jed,nz,
ntr)) ; cs%tr(:,:,:,:) = 0.0
137 if (cs%mask_tracers)
then 138 allocate(cs%tr_aux(isd:ied,jsd:jed,nz,
ntr)) ; cs%tr_aux(:,:,:,:) = 0.0
142 if (m < 10)
then ;
write(name,
'("tr_D",I1.1)') m
143 else ;
write(name,
'("tr_D",I2.2)') m ;
endif 144 write(longname,
'("Concentration of ISOMIP Tracer ",I2.2)') m
145 cs%tr_desc(m) =
var_desc(name, units=
"kg kg-1", longname=longname, caller=mdl)
149 tr_ptr => cs%tr(:,:,:,m)
153 call register_tracer(tr_ptr, cs%tr_desc(m), param_file, hi, gv, tr_reg, &
154 tr_desc_ptr=cs%tr_desc(m))
159 if (cs%coupled_tracers) &
161 flux_type=
' ', implementation=
' ', caller=
"register_ISOMIP_tracer")
165 register_isomip_tracer = .true.
171 ALE_sponge_CSp, diag_to_Z_CSp)
175 logical,
intent(in) :: restart
176 type(time_type),
target,
intent(in) :: day
177 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
178 type(
diag_ctrl),
target,
intent(in) :: diag
184 real,
allocatable :: temp(:,:,:)
185 real,
pointer,
dimension(:,:,:) :: &
186 OBC_tr1_u => null(), &
190 character(len=16) :: name
191 character(len=72) :: longname
192 character(len=48) :: units
193 character(len=48) :: flux_units
195 real,
pointer :: tr_ptr(:,:,:) => null()
201 real :: e(szk_(g)+1), e_top, e_bot, d_tr
202 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m
203 integer :: IsdB, IedB, JsdB, JedB
205 if (.not.
associated(cs))
return 206 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
207 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
208 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
209 h_neglect = gv%H_subroundoff
214 if (.not.restart)
then 215 if (len_trim(cs%tracer_IC_file) >= 1)
then 217 if (.not.
file_exists(cs%tracer_IC_file, g%Domain)) &
218 call mom_error(fatal,
"ISOMIP_initialize_tracer: Unable to open "// &
221 call query_vardesc(cs%tr_desc(m), name, caller=
"initialize_ISOMIP_tracer")
222 call read_data(cs%tracer_IC_file, trim(name), &
223 cs%tr(:,:,:,m), domain=g%Domain%mpp_domain)
227 do k=1,nz ;
do j=js,je ;
do i=is,ie
229 enddo ;
enddo ;
enddo 265 if (gv%Boussinesq)
then ; flux_units =
"kg kg-1 m3 s-1" 266 else ; flux_units =
"kg s-1" ;
endif 270 call query_vardesc(cs%tr_desc(m), name, units=units, longname=longname, &
271 caller=
"initialize_ISOMIP_tracer")
272 cs%id_tracer(m) = register_diag_field(
"ocean_model", trim(name), cs%diag%axesTL, &
273 day, trim(longname) , trim(units))
274 cs%id_tr_adx(m) = register_diag_field(
"ocean_model", trim(name)//
"_adx", &
275 cs%diag%axesCuL, day, trim(longname)//
" advective zonal flux" , &
277 cs%id_tr_ady(m) = register_diag_field(
"ocean_model", trim(name)//
"_ady", &
278 cs%diag%axesCvL, day, trim(longname)//
" advective meridional flux" , &
280 cs%id_tr_dfx(m) = register_diag_field(
"ocean_model", trim(name)//
"_dfx", &
281 cs%diag%axesCuL, day, trim(longname)//
" diffusive zonal flux" , &
283 cs%id_tr_dfy(m) = register_diag_field(
"ocean_model", trim(name)//
"_dfy", &
284 cs%diag%axesCvL, day, trim(longname)//
" diffusive zonal flux" , &
286 if (cs%id_tr_adx(m) > 0)
call safe_alloc_ptr(cs%tr_adx(m)%p,isdb,iedb,jsd,jed,nz)
287 if (cs%id_tr_ady(m) > 0)
call safe_alloc_ptr(cs%tr_ady(m)%p,isd,ied,jsdb,jedb,nz)
288 if (cs%id_tr_dfx(m) > 0)
call safe_alloc_ptr(cs%tr_dfx(m)%p,isdb,iedb,jsd,jed,nz)
289 if (cs%id_tr_dfy(m) > 0)
call safe_alloc_ptr(cs%tr_dfy(m)%p,isd,ied,jsdb,jedb,nz)
292 if ((cs%id_tr_adx(m) > 0) .or. (cs%id_tr_ady(m) > 0) .or. &
293 (cs%id_tr_dfx(m) > 0) .or. (cs%id_tr_dfy(m) > 0)) &
295 cs%tr_ady(m)%p, cs%tr_dfx(m)%p, cs%tr_dfy(m)%p)
298 day, g, diag_to_z_csp)
307 evap_CFL_limit, minimum_forcing_depth)
310 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h_old, h_new, ea, eb
311 type(
forcing),
intent(in) :: fluxes
312 real,
intent(in) :: dt
314 real,
optional,
intent(in) :: evap_CFL_limit
315 real,
optional,
intent(in) :: minimum_forcing_depth
338 real :: c1(szi_(g),szk_(g))
339 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work
340 real :: melt(szi_(g),szj_(g))
342 integer :: i, j, k, is, ie, js, je, nz, m
343 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
345 if (.not.
associated(cs))
return 347 melt(:,:) = fluxes%iceshelf_melt
350 mmax = maxval(melt(is:ie,js:je))
351 call max_across_pes(mmax)
355 do j=js,je ;
do i=is,ie
356 if (melt(i,j) > 0.0)
then 358 cs%tr(i,j,1:2,m) = melt(i,j)/mmax
360 cs%tr(i,j,1:2,m) = 0.0
365 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then 367 do k=1,nz ;
do j=js,je ;
do i=is,ie
368 h_work(i,j,k) = h_old(i,j,k)
369 enddo ;
enddo ; enddo;
371 evap_cfl_limit, minimum_forcing_depth)
380 if (cs%mask_tracers)
then 381 do m = 1,
ntr ;
if (cs%id_tracer(m) > 0)
then 382 do k=1,nz ;
do j=js,je ;
do i=is,ie
383 if (h_new(i,j,k) < 1.1*gv%Angstrom)
then 384 cs%tr_aux(i,j,k,m) = cs%land_val(m)
386 cs%tr_aux(i,j,k,m) = cs%tr(i,j,k,m)
388 enddo ;
enddo ;
enddo 393 if (cs%mask_tracers)
then 394 if (cs%id_tracer(m)>0) &
395 call post_data(cs%id_tracer(m),cs%tr_aux(:,:,:,m),cs%diag)
397 if (cs%id_tracer(m)>0) &
398 call post_data(cs%id_tracer(m),cs%tr(:,:,:,m),cs%diag)
400 if (cs%id_tr_adx(m)>0) &
401 call post_data(cs%id_tr_adx(m),cs%tr_adx(m)%p(:,:,:),cs%diag)
402 if (cs%id_tr_ady(m)>0) &
403 call post_data(cs%id_tr_ady(m),cs%tr_ady(m)%p(:,:,:),cs%diag)
404 if (cs%id_tr_dfx(m)>0) &
405 call post_data(cs%id_tr_dfx(m),cs%tr_dfx(m)%p(:,:,:),cs%diag)
406 if (cs%id_tr_dfy(m)>0) &
407 call post_data(cs%id_tr_dfy(m),cs%tr_dfy(m)%p(:,:,:),cs%diag)
416 type(
surface),
intent(inout) :: state
417 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
419 integer :: i, j, m, is, ie, js, je, nz
420 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
422 if (.not.
associated(cs))
return 424 if (cs%coupled_tracers)
then 429 ind_csurf, is, ie, js, je)
439 if (
associated(cs))
then 440 if (
associated(cs%tr))
deallocate(cs%tr)
441 if (
associated(cs%tr_aux))
deallocate(cs%tr_aux)
443 if (
associated(cs%tr_adx(m)%p))
deallocate(cs%tr_adx(m)%p)
444 if (
associated(cs%tr_ady(m)%p))
deallocate(cs%tr_ady(m)%p)
445 if (
associated(cs%tr_dfx(m)%p))
deallocate(cs%tr_dfx(m)%p)
446 if (
associated(cs%tr_dfy(m)%p))
deallocate(cs%tr_dfy(m)%p)
The following structure contains pointers to various fields which may be used describe the surface st...
type(vardesc) function, public var_desc(name, units, longname, hor_grid, z_grid, t_grid, cmor_field_name, cmor_units, conversion, caller)
Returns a vardesc type whose elements have been filled with the provided fields. The argument name is...
This module implements boundary forcing for MOM6.
integer function, public aof_set_coupler_flux(name, flux_type, implementation, atm_tr_index, param, flag, ice_restart_file, ocean_restart_file, units, caller)
Ocean grid type. See mom_grid for details.
Provides the ocean grid type.
subroutine, public isomip_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, evap_CFL_limit, minimum_forcing_depth)
This subroutine applies diapycnal diffusion and any other column.
This module contains the routines used to set up and use a set of (one for now) dynamically passive t...
This module contains I/O framework code.
Defines the horizontal index type (hor_index_type) used for providing index ranges.
subroutine, public set_up_ale_sponge_field(sp_val, G, f_ptr, CS)
This subroutine stores the reference profile at h points for the variable.
This module contains the routines used to apply sponge layers when using the ALE mode. Applying sponges requires the following: (1) initialize_ALE_sponge (2) set_up_ALE_sponge_field (tracers) and set_up_ALE_sponge_vel_field (vel) (3) apply_ALE_sponge (4) init_ALE_sponge_diags (not being used for now) (5) ALE_sponge_end (not being used for now)
SPONGE control structure.
Container for horizontal index ranges for data, computational and global domains. ...
subroutine, public register_tracer(tr1, tr_desc, param_file, HI, GV, Reg, tr_desc_ptr, ad_x, ad_y, df_x, df_y, OBC_inflow, OBC_in_u, OBC_in_v, ad_2d_x, ad_2d_y, df_2d_x, df_2d_y, advection_xy)
This subroutine registers a tracer to be advected and laterally diffused.
subroutine, public initialize_isomip_tracer(restart, day, G, GV, h, diag, OBC, CS, ALE_sponge_CSp, diag_to_Z_CSp)
Initializes the NTR tracer fields in tr(:,:,:,:)
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
subroutine, public applytracerboundaryfluxesinout(G, GV, Tr, dt, fluxes, h, evap_CFL_limit, minimum_forcing_depth, in_flux_optional, out_flux_optional, update_h_opt)
This routine is modeled after applyBoundaryFluxesInOut in MOM_diabatic_aux.F90 NOTE: Please note that...
Type to carry basic tracer information.
This module contains routines that implement physical fluxes of tracers (e.g. due to surface fluxes o...
subroutine, public register_z_tracer(tr_ptr, name, long_name, units, Time, G, CS, standard_name, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name)
This subroutine registers a tracer to be output in depth space.
subroutine, public add_tracer_obc_values(name, Reg, OBC_inflow, OBC_in_u, OBC_in_v)
This subroutine adds open boundary condition concentrations for a tracer that has previously been reg...
logical function, public register_isomip_tracer(HI, GV, param_file, CS, tr_Reg, restart_CS)
This subroutine is used to register tracer fields.
subroutine, public add_tracer_diagnostics(name, Reg, ad_x, ad_y, df_x, df_y, ad_2d_x, ad_2d_y, df_2d_x, df_2d_y, advection_xy)
This subroutine adds diagnostic arrays for a tracer that has previously been registered by a call to ...
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine, public set_coupler_values(array_in, BC_struc, BC_index, BC_element, is, ie, js, je, conversion)
Type for describing a variable, typically a tracer.
subroutine, public isomip_tracer_end(CS)
subroutine, public tracer_vertdiff(h_old, ea, eb, dt, tr, G, GV, sfc_flux, btm_flux, btm_reservoir, sink_rate, convert_flux_in)
This subroutine solves a tridiagonal equation for the final tracer concentrations after the dual-entr...
subroutine, public query_vardesc(vd, name, units, longname, hor_grid, z_grid, t_grid, cmor_field_name, cmor_units, conversion, caller)
This routine queries vardesc.
Controls where open boundary conditions are applied.
subroutine, public mom_error(level, message, all_print)
subroutine, public isomip_tracer_surface_state(state, h, G, CS)
This particular tracer package does not report anything back to the coupler.