1 module mom_generic_tracer
5 #include <MOM_memory.h>
7 #ifdef _USE_GENERIC_TRACER
8 #include <fms_platform.h>
10 use mpp_mod,
only: stdout, mpp_error, fatal,warning,note
11 use field_manager_mod,
only: fm_get_index,fm_string_len
13 use generic_tracer,
only: generic_tracer_register, generic_tracer_get_diag_list
14 use generic_tracer,
only: generic_tracer_init, generic_tracer_source, generic_tracer_register_diag
15 use generic_tracer,
only: generic_tracer_coupler_get, generic_tracer_coupler_set
16 use generic_tracer,
only: generic_tracer_end, generic_tracer_get_list, do_generic_tracer
17 use generic_tracer,
only: generic_tracer_update_from_bottom,generic_tracer_vertdiff_g
18 use generic_tracer,
only: generic_tracer_coupler_accumulate
20 use g_tracer_utils,
only: g_tracer_get_name,g_tracer_set_values,g_tracer_set_common,g_tracer_get_common
21 use g_tracer_utils,
only: g_tracer_get_next,g_tracer_type,g_tracer_is_prog,g_tracer_flux_init
22 use g_tracer_utils,
only: g_tracer_send_diag,g_tracer_get_values
23 use g_tracer_utils,
only: g_tracer_get_pointer,g_tracer_get_alias,g_tracer_set_csdiag
48 implicit none ;
private
49 logical :: g_registered = .false.
51 public register_mom_generic_tracer, initialize_mom_generic_tracer
52 public mom_generic_tracer_column_physics, mom_generic_tracer_surface_state
53 public end_mom_generic_tracer, mom_generic_tracer_get
54 public mom_generic_tracer_stock
55 public mom_generic_flux_init
56 public mom_generic_tracer_min_max
57 public mom_generic_tracer_fluxes_accumulate
59 type,
public :: mom_generic_tracer_cs ;
private
60 character(len = 200) :: IC_file
63 real :: tracer_IC_val = 0.0
64 real :: tracer_land_val = -1.0
65 logical :: tracers_may_reinit
69 type(diag_ctrl),
pointer :: diag => null()
71 type(MOM_restart_CS),
pointer :: restart_CSp => null()
75 type(g_tracer_type),
pointer :: g_tracer_list => null()
79 end type mom_generic_tracer_cs
82 #include "version_variable.h"
89 function register_mom_generic_tracer(HI, GV, param_file, CS, tr_Reg, restart_CS)
90 type(hor_index_type),
intent(in) :: HI
91 type(verticalGrid_type),
intent(in) :: GV
92 type(param_file_type),
intent(in) :: param_file
93 type(MOM_generic_tracer_CS),
pointer :: CS
94 type(tracer_registry_type),
pointer :: tr_Reg
96 type(MOM_restart_CS),
pointer :: restart_CS
99 logical :: register_MOM_generic_tracer
101 character(len=fm_string_len),
parameter :: sub_name =
'register_MOM_generic_tracer'
102 character(len=200) :: inputdir
105 integer :: ntau, k,i,j,axes(3)
106 type(g_tracer_type),
pointer :: g_tracer,g_tracer_next
107 character(len=fm_string_len) :: g_tracer_name,longname,units
108 real,
dimension(:,:,:,:),
pointer :: tr_field
109 real,
dimension(:,:,:),
pointer :: tr_ptr
110 real,
dimension(HI%isd:HI%ied, HI%jsd:HI%jed,GV%ke) :: grid_tmask
111 integer,
dimension(HI%isd:HI%ied, HI%jsd:HI%jed) :: grid_kmt
113 register_mom_generic_tracer = .false.
114 if (
associated(cs))
then
115 call mpp_error(warning,
"register_MOM_generic_tracer called with an "// &
116 "associated control structure.")
124 if (.not. g_registered)
then
125 call generic_tracer_register
126 g_registered = .true.
131 call log_version(param_file, sub_name, version,
"")
132 call get_param(param_file, sub_name,
"GENERIC_TRACER_IC_FILE", cs%IC_file, &
133 "The file in which the generic trcer initial values can "//&
134 "be found, or an empty string for internal initialization.", &
136 if ((len_trim(cs%IC_file) > 0) .and. (scan(cs%IC_file,
'/') == 0))
then
138 call get_param(param_file, sub_name,
"INPUTDIR", inputdir, default=
".")
139 cs%IC_file = trim(slasher(inputdir))//trim(cs%IC_file)
140 call log_param(param_file, sub_name,
"INPUTDIR/GENERIC_TRACER_IC_FILE", cs%IC_file)
142 call get_param(param_file, sub_name,
"GENERIC_TRACER_IC_FILE_IS_Z", cs%Z_IC_file, &
143 "If true, GENERIC_TRACER_IC_FILE is in depth space, not "//&
144 "layer space.",default=.false.)
145 call get_param(param_file, sub_name,
"TRACERS_MAY_REINIT", cs%tracers_may_reinit, &
146 "If true, tracers may go through the initialization code "//&
147 "if they are not found in the restart files. Otherwise "//&
148 "it is a fatal error if tracers are not found in the "//&
149 "restart files of a restarted run.", default=.false.)
151 cs%restart_CSp => restart_cs
161 grid_tmask(:,:,:) = 0.0
168 call generic_tracer_init(hi%isc,hi%iec,hi%jsc,hi%jec,hi%isd,hi%ied,hi%jsd,hi%jed,&
169 gv%ke,ntau,axes,grid_tmask,grid_kmt,set_time(0,0))
177 call generic_tracer_get_list(cs%g_tracer_list)
178 if (.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal, trim(sub_name)//&
179 ": No tracer in the list.")
182 g_tracer=>cs%g_tracer_list
184 call g_tracer_get_alias(g_tracer,g_tracer_name)
186 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'field',tr_field)
187 call g_tracer_get_values(g_tracer,g_tracer_name,
'longname', longname)
188 call g_tracer_get_values(g_tracer,g_tracer_name,
'units',units )
191 tr_ptr => tr_field(:,:,:,1)
193 if (g_tracer_is_prog(g_tracer))
then
194 call register_tracer(tr_ptr, tr_reg, param_file, hi, gv, &
195 name=g_tracer_name, longname=longname, units=units, &
196 registry_diags=.false., &
197 restart_cs=restart_cs, mandatory=.not.cs%tracers_may_reinit)
200 restart_cs, longname=longname, units=units)
204 call g_tracer_get_next(g_tracer, g_tracer_next)
205 if (.NOT.
associated(g_tracer_next))
exit
206 g_tracer=>g_tracer_next
210 register_mom_generic_tracer = .true.
211 end function register_mom_generic_tracer
222 subroutine initialize_mom_generic_tracer(restart, day, G, GV, US, h, param_file, diag, OBC, CS, &
223 sponge_CSp, ALE_sponge_CSp)
224 logical,
intent(in) :: restart
226 type(time_type),
target,
intent(in) :: day
227 type(ocean_grid_type),
intent(inout) :: G
228 type(verticalGrid_type),
intent(in) :: GV
229 type(unit_scale_type),
intent(in) :: US
230 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
231 type(param_file_type),
intent(in) :: param_file
232 type(diag_ctrl),
target,
intent(in) :: diag
233 type(ocean_OBC_type),
pointer :: OBC
235 type(MOM_generic_tracer_CS),
pointer :: CS
236 type(sponge_CS),
pointer :: sponge_CSp
237 type(ALE_sponge_CS),
pointer :: ALE_sponge_CSp
240 character(len=fm_string_len),
parameter :: sub_name =
'initialize_MOM_generic_tracer'
242 integer :: i, j, k, isc, iec, jsc, jec, nk
243 type(g_tracer_type),
pointer :: g_tracer,g_tracer_next
244 character(len=fm_string_len) :: g_tracer_name
245 real,
dimension(:,:,:,:),
pointer :: tr_field
246 real,
dimension(:,:,:),
pointer :: tr_ptr
247 real,
dimension(G%isd:G%ied, G%jsd:G%jed,1:G%ke) :: grid_tmask
248 integer,
dimension(G%isd:G%ied, G%jsd:G%jed) :: grid_kmt
254 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec ; nk = g%ke
258 if (.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal, trim(sub_name)//&
259 ": No tracer in the list.")
261 g_tracer=>cs%g_tracer_list
264 if (index(cs%IC_file,
'_NULL_') /= 0)
then
265 call mom_error(warning,
"The name of the IC_file "//trim(cs%IC_file)//&
266 " indicates no MOM initialization was asked for the generic tracers."//&
267 "Bypassing the MOM initialization of ALL generic tracers!")
270 call g_tracer_get_alias(g_tracer,g_tracer_name)
271 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'field',tr_field)
272 tr_ptr => tr_field(:,:,:,1)
274 if (.not.restart .or. (cs%tracers_may_reinit .and. &
277 if (g_tracer%requires_src_info )
then
278 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
279 "initializing generic tracer "//trim(g_tracer_name)//&
280 " using MOM_initialize_tracer_from_Z ")
282 call mom_initialize_tracer_from_z(h, tr_ptr, g, gv, us, param_file, &
283 src_file = g_tracer%src_file, &
284 src_var_nam = g_tracer%src_var_name, &
285 src_var_unit_conversion = g_tracer%src_var_unit_conversion,&
286 src_var_record = g_tracer%src_var_record, &
287 src_var_gridspec = g_tracer%src_var_gridspec )
290 do k=1,nk ;
do j=jsc,jec ;
do i=isc,iec
291 if (tr_ptr(i,j,k) /= cs%tracer_land_val)
then
292 if (tr_ptr(i,j,k) < g_tracer%src_var_valid_min) tr_ptr(i,j,k) = g_tracer%src_var_valid_min
296 enddo ;
enddo ;
enddo
299 if ( (trim(g_tracer_name) ==
'cased') .or. (trim(g_tracer_name) ==
'ca13csed') )
then
300 do k=2,nk ;
do j=jsc,jec ;
do i=isc,iec
301 if (tr_ptr(i,j,k) /= cs%tracer_land_val)
then
304 enddo ;
enddo ;
enddo
306 elseif(.not. g_tracer%requires_restart)
then
308 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
309 "skip initialization of generic tracer "//trim(g_tracer_name))
312 if (len_trim(cs%IC_file) > 0)
then
314 if (.not.
file_exists(cs%IC_file))
call mom_error(fatal, &
315 "initialize_MOM_Generic_tracer: Unable to open "//cs%IC_file)
316 if (cs%Z_IC_file)
then
317 ok = tracer_z_init(tr_ptr, h, cs%IC_file, g_tracer_name, g, us)
319 ok = tracer_z_init(tr_ptr, h, cs%IC_file, trim(g_tracer_name), g, us)
320 if (.not.ok)
call mom_error(fatal,
"initialize_MOM_Generic_tracer: "//&
321 "Unable to read "//trim(g_tracer_name)//
" from "//&
322 trim(cs%IC_file)//
".")
324 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
325 "initialized generic tracer "//trim(g_tracer_name)//&
326 " using Generic Tracer File on Z: "//cs%IC_file)
329 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
330 "Using Generic Tracer IC file on native grid "//trim(cs%IC_file)//&
331 " for tracer "//trim(g_tracer_name))
332 call mom_read_data(cs%IC_file, trim(g_tracer_name), tr_ptr, g%Domain)
335 call mom_error(fatal,
"initialize_MOM_generic_tracer: "//&
336 "check Generic Tracer IC filename "//trim(cs%IC_file)//&
337 " for tracer "//trim(g_tracer_name))
344 call g_tracer_get_next(g_tracer, g_tracer_next)
345 if (.NOT.
associated(g_tracer_next))
exit
346 g_tracer=>g_tracer_next
354 grid_tmask(:,:,:) = 0.0
356 do j = g%jsd, g%jed ;
do i = g%isd, g%ied
357 if (g%mask2dT(i,j) > 0)
then
358 grid_tmask(i,j,:) = 1.0
362 call g_tracer_set_common(g%isc,g%iec,g%jsc,g%jec,g%isd,g%ied,g%jsd,g%jed,&
363 gv%ke,1,cs%diag%axesTL%handles,grid_tmask,grid_kmt,day)
367 #ifdef _USE_MOM6_DIAG
368 call g_tracer_set_csdiag(cs%diag)
370 call generic_tracer_register_diag()
371 #ifdef _USE_MOM6_DIAG
372 call g_tracer_set_csdiag(cs%diag)
375 cs%H_to_m = gv%H_to_m
377 end subroutine initialize_mom_generic_tracer
389 subroutine mom_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml, dt, G, GV, CS, tv, optics, &
390 evap_CFL_limit, minimum_forcing_depth)
391 type(ocean_grid_type),
intent(in) :: G
392 type(verticalGrid_type),
intent(in) :: GV
393 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
395 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
397 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
400 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
403 type(forcing),
intent(in) :: fluxes
405 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: Hml
406 real,
intent(in) :: dt
407 type(MOM_generic_tracer_CS),
pointer :: CS
408 type(thermo_var_ptrs),
intent(in) :: tv
409 type(optics_type),
intent(in) :: optics
410 real,
optional,
intent(in) :: evap_CFL_limit
412 real,
optional,
intent(in) :: minimum_forcing_depth
418 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_column_physics'
420 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
421 character(len=fm_string_len) :: g_tracer_name
422 real,
dimension(:,:),
pointer :: stf_array,trunoff_array,runoff_tracer_flux_array
424 real :: surface_field(SZI_(G),SZJ_(G))
427 real,
dimension(G%isd:G%ied,G%jsd:G%jed,G%ke) :: rho_dzt, dzt
428 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work
429 integer :: i, j, k, isc, iec, jsc, jec, nk
431 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec ; nk = g%ke
434 if (.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal,&
435 trim(sub_name)//
": No tracer in the list.")
437 #ifdef _USE_MOM6_DIAG
438 call g_tracer_set_csdiag(cs%diag)
452 g_tracer=>cs%g_tracer_list
454 if (_allocated(g_tracer%trunoff))
then
455 call g_tracer_get_alias(g_tracer,g_tracer_name)
456 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'stf', stf_array)
457 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'trunoff',trunoff_array)
458 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'runoff_tracer_flux',runoff_tracer_flux_array)
460 runoff_tracer_flux_array = trunoff_array * fluxes%lrunoff
461 stf_array = stf_array + runoff_tracer_flux_array
465 call g_tracer_get_next(g_tracer, g_tracer_next)
466 if (.NOT.
associated(g_tracer_next))
exit
467 g_tracer=>g_tracer_next
475 rho_dzt(:,:,:) = gv%H_to_kg_m2 * gv%Angstrom_H
476 do k = 1, nk ;
do j = jsc, jec ;
do i = isc, iec
477 rho_dzt(i,j,k) = gv%H_to_kg_m2 * h_old(i,j,k)
478 enddo ;
enddo ;
enddo
481 do k = 1, nk ;
do j = jsc, jec ;
do i = isc, iec
482 dzt(i,j,k) = gv%H_to_m * h_old(i,j,k)
483 enddo ;
enddo ;
enddo
485 do j=jsc,jec ;
do i=isc,iec
486 surface_field(i,j) = tv%S(i,j,1)
488 sosga = global_area_mean(surface_field, g)
494 call generic_tracer_source(tv%T,tv%S,rho_dzt,dzt,hml,g%isd,g%jsd,1,dt,&
495 g%areaT,get_diag_time_end(cs%diag),&
496 optics%nbands, optics%max_wavelength_band, optics%sw_pen_band, optics%opacity_band, &
497 internal_heat=tv%internal_heat, frunoff=fluxes%frunoff, sosga=sosga)
501 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
502 g_tracer=>cs%g_tracer_list
504 if (g_tracer_is_prog(g_tracer))
then
505 do k=1,nk ;
do j=jsc,jec ;
do i=isc,iec
506 h_work(i,j,k) = h_old(i,j,k)
507 enddo ;
enddo ;
enddo
508 call applytracerboundaryfluxesinout(g, gv, g_tracer%field(:,:,:,1), dt, fluxes, h_work, &
509 evap_cfl_limit, minimum_forcing_depth)
513 call g_tracer_get_next(g_tracer, g_tracer_next)
514 if (.NOT.
associated(g_tracer_next))
exit
515 g_tracer=>g_tracer_next
524 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
526 call generic_tracer_vertdiff_g(h_work, ea, eb, dt, gv%kg_m2_to_H, gv%m_to_H, 1)
529 call generic_tracer_vertdiff_g(h_old, ea, eb, dt, gv%kg_m2_to_H, gv%m_to_H, 1)
535 call generic_tracer_update_from_bottom(dt, 1, get_diag_time_end(cs%diag))
538 call g_tracer_send_diag(cs%g_tracer_list, get_diag_time_end(cs%diag), tau=1)
539 #ifdef _USE_MOM6_DIAG
540 call g_tracer_set_csdiag(cs%diag)
544 end subroutine mom_generic_tracer_column_physics
551 function mom_generic_tracer_stock(h, stocks, G, GV, CS, names, units, stock_index)
552 type(ocean_grid_type),
intent(in) :: G
553 type(verticalGrid_type),
intent(in) :: GV
554 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
555 real,
dimension(:),
intent(out) :: stocks
557 type(MOM_generic_tracer_CS),
pointer :: CS
558 character(len=*),
dimension(:),
intent(out) :: names
559 character(len=*),
dimension(:),
intent(out) :: units
560 integer,
optional,
intent(in) :: stock_index
562 integer :: MOM_generic_tracer_stock
566 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
567 real,
dimension(:,:,:,:),
pointer :: tr_field
568 real,
dimension(:,:,:),
pointer :: tr_ptr
569 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_stock'
571 integer :: i, j, k, is, ie, js, je, nz, m
572 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
574 mom_generic_tracer_stock = 0
575 if (.not.
associated(cs))
return
577 if (
present(stock_index))
then ;
if (stock_index > 0)
then
584 if (.NOT.
associated(cs%g_tracer_list))
return
586 m=1 ; g_tracer=>cs%g_tracer_list
588 call g_tracer_get_alias(g_tracer,names(m))
589 call g_tracer_get_values(g_tracer,names(m),
'units',units(m))
590 units(m) = trim(units(m))//
" kg"
591 call g_tracer_get_pointer(g_tracer,names(m),
'field',tr_field)
594 tr_ptr => tr_field(:,:,:,1)
595 do k=1,nz ;
do j=js,je ;
do i=is,ie
596 stocks(m) = stocks(m) + tr_ptr(i,j,k) * &
597 (g%mask2dT(i,j) * g%areaT(i,j) * h(i,j,k))
598 enddo ;
enddo ;
enddo
599 stocks(m) = gv%H_to_kg_m2 * stocks(m)
602 call g_tracer_get_next(g_tracer, g_tracer_next)
603 if (.NOT.
associated(g_tracer_next))
exit
604 g_tracer=>g_tracer_next
608 mom_generic_tracer_stock = m
610 end function mom_generic_tracer_stock
615 function mom_generic_tracer_min_max(ind_start, got_minmax, gmin, gmax, xgmin, ygmin, zgmin, &
616 xgmax, ygmax, zgmax , G, CS, names, units)
617 use mpp_utilities_mod,
only: mpp_array_global_min_max
618 integer,
intent(in) :: ind_start
619 logical,
dimension(:),
intent(out) :: got_minmax
621 real,
dimension(:),
intent(out) :: gmin
623 real,
dimension(:),
intent(out) :: gmax
625 real,
dimension(:),
intent(out) :: xgmin
626 real,
dimension(:),
intent(out) :: ygmin
627 real,
dimension(:),
intent(out) :: zgmin
628 real,
dimension(:),
intent(out) :: xgmax
629 real,
dimension(:),
intent(out) :: ygmax
630 real,
dimension(:),
intent(out) :: zgmax
631 type(ocean_grid_type),
intent(in) :: G
632 type(MOM_generic_tracer_CS),
pointer :: CS
633 character(len=*),
dimension(:),
intent(out) :: names
634 character(len=*),
dimension(:),
intent(out) :: units
635 integer :: MOM_generic_tracer_min_max
639 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
640 real,
dimension(:,:,:,:),
pointer :: tr_field
641 real,
dimension(:,:,:),
pointer :: tr_ptr
642 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_min_max'
644 real,
dimension(:,:,:),
pointer :: grid_tmask
645 integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau
647 integer :: i, j, k, is, ie, js, je, nz, m
648 real,
allocatable,
dimension(:) :: geo_z
650 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
652 mom_generic_tracer_min_max = 0
653 if (.not.
associated(cs))
return
655 if (.NOT.
associated(cs%g_tracer_list))
return
658 call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask)
663 do k=1,nk ; geo_z(k) = real(k) ;
enddo
665 m=ind_start ; g_tracer=>cs%g_tracer_list
667 call g_tracer_get_alias(g_tracer,names(m))
668 call g_tracer_get_values(g_tracer,names(m),
'units',units(m))
669 units(m) = trim(units(m))//
" kg"
670 call g_tracer_get_pointer(g_tracer,names(m),
'field',tr_field)
675 tr_ptr => tr_field(:,:,:,1)
677 call mpp_array_global_min_max(tr_ptr, grid_tmask,isd,jsd,isc,iec,jsc,jec,nk , gmin(m), gmax(m), &
678 g%geoLonT,g%geoLatT,geo_z,xgmin(m), ygmin(m), zgmin(m), &
679 xgmax(m), ygmax(m), zgmax(m))
681 got_minmax(m) = .true.
684 call g_tracer_get_next(g_tracer, g_tracer_next)
685 if (.NOT.
associated(g_tracer_next))
exit
686 g_tracer=>g_tracer_next
690 mom_generic_tracer_min_max = m
692 end function mom_generic_tracer_min_max
700 subroutine mom_generic_tracer_surface_state(state, h, G, CS)
701 type(ocean_grid_type),
intent(in) :: G
702 type(surface),
intent(inout) :: state
704 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
705 type(MOM_generic_tracer_CS),
pointer :: CS
710 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_surface_state'
711 real,
dimension(G%isd:G%ied,G%jsd:G%jed,1:G%ke,1) :: rho0
712 real,
dimension(G%isd:G%ied,G%jsd:G%jed,1:G%ke) :: dzt
713 type(g_tracer_type),
pointer :: g_tracer
719 dzt(:,:,:) = cs%H_to_m * h(:,:,:)
721 sosga = global_area_mean(state%SSS, g)
723 call generic_tracer_coupler_set(state%tr_fields,&
727 ilb=g%isd, jlb=g%jsd,&
729 tau=1,sosga=sosga,model_time=get_diag_time_end(cs%diag))
740 end subroutine mom_generic_tracer_surface_state
743 subroutine mom_generic_flux_init(verbosity)
744 integer,
optional,
intent(in) :: verbosity
747 character(len=fm_string_len) :: g_tracer_name,longname, package,units,old_package,file_in,file_out
748 real :: const_init_value
749 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_flux_init'
750 type(g_tracer_type),
pointer :: g_tracer_list,g_tracer,g_tracer_next
752 if (.not. g_registered)
then
753 call generic_tracer_register
754 g_registered = .true.
757 call generic_tracer_get_list(g_tracer_list)
758 if (.NOT.
associated(g_tracer_list))
then
759 call mpp_error(warning, trim(sub_name)//
": No generic tracer in the list.")
763 g_tracer=>g_tracer_list
766 call g_tracer_flux_init(g_tracer)
769 call g_tracer_get_next(g_tracer, g_tracer_next)
770 if (.NOT.
associated(g_tracer_next))
exit
771 g_tracer=>g_tracer_next
775 end subroutine mom_generic_flux_init
777 subroutine mom_generic_tracer_fluxes_accumulate(flux_tmp, weight)
778 type(forcing),
intent(in) :: flux_tmp
780 real,
intent(in) :: weight
782 call generic_tracer_coupler_accumulate(flux_tmp%tr_fluxes, weight)
784 end subroutine mom_generic_tracer_fluxes_accumulate
787 subroutine mom_generic_tracer_get(name,member,array, CS)
788 character(len=*),
intent(in) :: name
789 character(len=*),
intent(in) :: member
790 real,
dimension(:,:,:),
intent(out) :: array
791 type(MOM_generic_tracer_CS),
pointer :: CS
793 real,
dimension(:,:,:),
pointer :: array_ptr
794 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_get'
796 call g_tracer_get_pointer(cs%g_tracer_list,name,member,array_ptr)
797 array(:,:,:) = array_ptr(:,:,:)
799 end subroutine mom_generic_tracer_get
802 subroutine end_mom_generic_tracer(CS)
803 type(MOM_generic_tracer_CS),
pointer :: CS
805 call generic_tracer_end
807 if (
associated(cs))
then
810 end subroutine end_mom_generic_tracer
812 #endif /* _USE_GENERIC_TRACER */
825 end module mom_generic_tracer