20 implicit none ;
private 22 #include <MOM_memory.h> 36 real,
dimension(:,:,:),
pointer :: t => null()
37 real :: obc_inflow_conc= 0.0
38 real,
dimension(:,:,:),
pointer :: obc_in_u => null()
40 real,
dimension(:,:,:),
pointer :: obc_in_v => null()
43 real,
dimension(:,:,:),
pointer :: ad_x => null()
44 real,
dimension(:,:,:),
pointer :: ad_y => null()
45 real,
dimension(:,:),
pointer :: ad2d_x => null()
47 real,
dimension(:,:),
pointer :: ad2d_y => null()
50 real,
dimension(:,:,:),
pointer :: df_x => null()
51 real,
dimension(:,:,:),
pointer :: df_y => null()
52 real,
dimension(:,:),
pointer :: df2d_x => null()
54 real,
dimension(:,:),
pointer :: df2d_y => null()
57 real,
dimension(:,:,:),
pointer :: advection_xy => null()
59 character(len=32) :: name
69 logical :: locked = .false.
78 subroutine register_tracer(tr1, tr_desc, param_file, HI, GV, Reg, tr_desc_ptr, ad_x, ad_y,&
79 df_x, df_y, OBC_inflow, OBC_in_u, OBC_in_v, &
80 ad_2d_x, ad_2d_y, df_2d_x, df_2d_y, advection_xy)
83 real,
dimension(SZI_(HI),SZJ_(HI),SZK_(GV)),
target :: tr1
84 type(
vardesc),
intent(in) :: tr_desc
87 type(
vardesc),
target,
optional :: tr_desc_ptr
93 real,
pointer,
dimension(:,:,:),
optional :: ad_x
94 real,
pointer,
dimension(:,:,:),
optional :: ad_y
95 real,
pointer,
dimension(:,:,:),
optional :: df_x
96 real,
pointer,
dimension(:,:,:),
optional :: df_y
98 real,
intent(in),
optional :: OBC_inflow
100 real,
pointer,
dimension(:,:,:),
optional :: OBC_in_u
102 real,
pointer,
dimension(:,:,:),
optional :: OBC_in_v
105 real,
dimension(:,:),
pointer,
optional :: ad_2d_x
106 real,
dimension(:,:),
pointer,
optional :: ad_2d_y
107 real,
dimension(:,:),
pointer,
optional :: df_2d_x
108 real,
dimension(:,:),
pointer,
optional :: df_2d_y
110 real,
pointer,
dimension(:,:,:),
optional :: advection_xy
114 character(len=256) :: mesg
118 if (reg%ntr>=max_fields_)
then 119 write(mesg,
'("Increase MAX_FIELDS_ in MOM_memory.h to at least ",I3," to allow for & 120 &all the tracers being registered via register_tracer.")') reg%ntr+1
121 call mom_error(fatal,
"MOM register_tracer: "//mesg)
123 reg%ntr = reg%ntr + 1
126 if (
present(tr_desc_ptr))
then 127 reg%Tr(ntr)%vd => tr_desc_ptr
129 allocate(reg%Tr(ntr)%vd) ; reg%Tr(ntr)%vd = tr_desc
135 "MOM register_tracer was called for variable "//trim(reg%Tr(ntr)%name)//&
136 " with a locked tracer registry.")
140 if (
present(ad_x))
then ;
if (
associated(ad_x)) reg%Tr(ntr)%ad_x => ad_x ;
endif 141 if (
present(ad_y))
then ;
if (
associated(ad_y)) reg%Tr(ntr)%ad_y => ad_y ;
endif 142 if (
present(df_x))
then ;
if (
associated(df_x)) reg%Tr(ntr)%df_x => df_x ;
endif 143 if (
present(df_y))
then ;
if (
associated(df_y)) reg%Tr(ntr)%df_y => df_y ;
endif 144 if (
present(obc_inflow)) reg%Tr(ntr)%OBC_inflow_conc = obc_inflow
145 if (
present(obc_in_u))
then ;
if (
associated(obc_in_u)) &
146 reg%Tr(ntr)%OBC_in_u => obc_in_u ;
endif 147 if (
present(obc_in_v))
then ;
if (
associated(obc_in_v)) &
148 reg%Tr(ntr)%OBC_in_v => obc_in_v ;
endif 149 if (
present(ad_2d_x))
then ;
if (
associated(ad_2d_x)) reg%Tr(ntr)%ad2d_x => ad_2d_x ;
endif 150 if (
present(ad_2d_y))
then ;
if (
associated(ad_2d_y)) reg%Tr(ntr)%ad2d_y => ad_2d_y ;
endif 151 if (
present(df_2d_x))
then ;
if (
associated(df_2d_x)) reg%Tr(ntr)%df2d_x => df_2d_x ;
endif 153 if (
present(advection_xy))
then ;
if (
associated(advection_xy)) reg%Tr(ntr)%advection_xy => advection_xy ;
endif 163 if (.not.
associated(reg))
call mom_error(warning, &
164 "lock_tracer_registry called with an unassocaited registry.")
174 character(len=*),
intent(in) :: name
176 real,
intent(in),
optional :: OBC_inflow
179 real,
pointer,
dimension(:,:,:),
optional :: OBC_in_u
181 real,
pointer,
dimension(:,:,:),
optional :: OBC_in_v
186 if (.not.
associated(reg))
call mom_error(fatal,
"add_tracer_OBC_values :"// &
187 "register_tracer must be called before add_tracer_OBC_values")
189 do m=1,reg%ntr ;
if (reg%Tr(m)%name == trim(name))
exit ;
enddo 191 if (m <= reg%ntr)
then 192 if (
present(obc_inflow)) reg%Tr(m)%OBC_inflow_conc = obc_inflow
193 if (
present(obc_in_u))
then ;
if (
associated(obc_in_u)) &
194 reg%Tr(m)%OBC_in_u => obc_in_u ;
endif 195 if (
present(obc_in_v))
then ;
if (
associated(obc_in_v)) &
196 reg%Tr(m)%OBC_in_v => obc_in_v ;
endif 198 call mom_error(fatal,
"MOM_tracer: register_tracer must be called for "//&
199 trim(name)//
" before add_tracer_OBC_values is called for it.")
208 ad_2d_x, ad_2d_y, df_2d_x, df_2d_y,&
210 character(len=*),
intent(in) :: name
212 real,
dimension(:,:,:),
pointer,
optional :: ad_x
213 real,
dimension(:,:,:),
pointer,
optional :: ad_y
214 real,
dimension(:,:,:),
pointer,
optional :: df_x
215 real,
dimension(:,:,:),
pointer,
optional :: df_y
216 real,
dimension(:,:),
pointer,
optional :: ad_2d_x
217 real,
dimension(:,:),
pointer,
optional :: ad_2d_y
218 real,
dimension(:,:),
pointer,
optional :: df_2d_x
219 real,
dimension(:,:),
pointer,
optional :: df_2d_y
221 real,
dimension(:,:,:),
pointer,
optional :: advection_xy
225 if (.not.
associated(reg))
call mom_error(fatal,
"add_tracer_diagnostics: "// &
226 "register_tracer must be called before add_tracer_diagnostics")
228 do m=1,reg%ntr ;
if (reg%Tr(m)%name == trim(name))
exit ;
enddo 230 if (m <= reg%ntr)
then 231 if (
present(ad_x))
then ;
if (
associated(ad_x)) reg%Tr(m)%ad_x => ad_x ;
endif 232 if (
present(ad_y))
then ;
if (
associated(ad_y)) reg%Tr(m)%ad_y => ad_y ;
endif 233 if (
present(df_x))
then ;
if (
associated(df_x)) reg%Tr(m)%df_x => df_x ;
endif 234 if (
present(df_y))
then ;
if (
associated(df_y)) reg%Tr(m)%df_y => df_y ;
endif 236 if (
present(ad_2d_x))
then ;
if (
associated(ad_2d_x)) reg%Tr(m)%ad2d_x => ad_2d_x ;
endif 237 if (
present(ad_2d_y))
then ;
if (
associated(ad_2d_y)) reg%Tr(m)%ad2d_y => ad_2d_y ;
endif 238 if (
present(df_2d_x))
then ;
if (
associated(df_2d_x)) reg%Tr(m)%df2d_x => df_2d_x ;
endif 239 if (
present(df_2d_y))
then ;
if (
associated(df_2d_y)) reg%Tr(m)%df2d_y => df_2d_y ;
endif 241 if (
present(advection_xy))
then ;
if (
associated(advection_xy)) reg%Tr(m)%advection_xy => advection_xy ;
endif 245 call mom_error(fatal,
"MOM_tracer: register_tracer must be called for "//&
246 trim(name)//
" before add_tracer_diagnostics is called for it.")
253 character(len=*),
intent(in) :: mesg
255 integer,
intent(in) :: ntr
258 integer :: is, ie, js, je, nz
259 integer :: i, j, k, m
261 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
263 call hchksum(tr(m)%t, mesg//trim(tr(m)%name), g%HI)
270 character(len=*),
intent(in) :: mesg
273 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
274 integer,
intent(in) :: ntr
276 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: tr_inv
278 integer :: is, ie, js, je, nz
279 integer :: i, j, k, m
281 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
283 do k=1,nz ;
do j=js,je ;
do i=is,ie
284 tr_inv(i,j,k) = tr(m)%t(i,j,k)*h(i,j,k)*g%areaT(i,j)*g%mask2dT(i,j)
285 enddo ;
enddo ;
enddo 287 if (
is_root_pe())
write(0,
'(A,1X,A5,1X,ES25.16,1X,A)')
"h-point: inventory", tr(m)%name, total_inv, mesg
297 integer,
save :: init_calls = 0
299 #include "version_variable.h" 300 character(len=40) :: mdl =
"MOM_tracer_registry" 301 character(len=256) :: mesg
303 if (.not.
associated(reg))
then ;
allocate(reg)
304 else ;
return ;
endif 309 init_calls = init_calls + 1
310 if (init_calls > 1)
then 311 write(mesg,
'("tracer_registry_init called ",I3, & 312 &" times with different registry pointers.")') init_calls
322 if (
associated(reg))
deallocate(reg)
subroutine, public tracer_registry_init(param_file, Reg)
This routine include declares and sets the variable "version".
Ocean grid type. See mom_grid for details.
Provides the ocean grid type.
subroutine, public mom_tracer_chksum(mesg, Tr, ntr, G)
This subroutine writes out chksums for tracers.
This module contains I/O framework code.
Defines the horizontal index type (hor_index_type) used for providing index ranges.
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.
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
Type to carry basic tracer information.
logical function, public is_root_pe()
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...
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 ...
subroutine, public mom_mesg(message, verb, all_print)
Type for describing a variable, typically a tracer.
subroutine, public tracer_registry_end(Reg)
This routine closes the tracer registry module.
subroutine, public lock_tracer_registry(Reg)
This subroutine locks the tracer registry to prevent the addition of more tracers. After locked=.true., can then register common diagnostics.
subroutine, public mom_tracer_chkinv(mesg, G, h, Tr, ntr)
Calculates and prints the global inventory of all tracers in the registry.
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.
subroutine, public mom_error(level, message, all_print)