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
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 ")
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
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
419 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_column_physics'
421 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
422 character(len=fm_string_len) :: g_tracer_name
423 real,
dimension(:,:),
pointer :: stf_array,trunoff_array,runoff_tracer_flux_array
425 real :: surface_field(SZI_(G),SZJ_(G))
428 real,
dimension(G%isd:G%ied,G%jsd:G%jed,G%ke) :: rho_dzt, dzt
429 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work
430 integer :: i, j, k, isc, iec, jsc, jec, nk
432 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec ; nk = g%ke
435 if (.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal,&
436 trim(sub_name)//
": No tracer in the list.")
438 #ifdef _USE_MOM6_DIAG
439 call g_tracer_set_csdiag(cs%diag)
453 g_tracer=>cs%g_tracer_list
455 if (_allocated(g_tracer%trunoff))
then
456 call g_tracer_get_alias(g_tracer,g_tracer_name)
457 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'stf', stf_array)
458 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'trunoff',trunoff_array)
459 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'runoff_tracer_flux',runoff_tracer_flux_array)
461 runoff_tracer_flux_array(:,:) = trunoff_array(:,:) * &
462 g%US%R_to_kg_m3*g%US%Z_to_m*g%US%s_to_T*fluxes%lrunoff(:,:)
463 stf_array = stf_array + runoff_tracer_flux_array
467 call g_tracer_get_next(g_tracer, g_tracer_next)
468 if (.NOT.
associated(g_tracer_next))
exit
469 g_tracer=>g_tracer_next
477 rho_dzt(:,:,:) = gv%H_to_kg_m2 * gv%Angstrom_H
478 do k = 1, nk ;
do j = jsc, jec ;
do i = isc, iec
479 rho_dzt(i,j,k) = gv%H_to_kg_m2 * h_old(i,j,k)
480 enddo ;
enddo ;
enddo
483 do k = 1, nk ;
do j = jsc, jec ;
do i = isc, iec
484 dzt(i,j,k) = gv%H_to_m * h_old(i,j,k)
485 enddo ;
enddo ;
enddo
487 do j=jsc,jec ;
do i=isc,iec
488 surface_field(i,j) = tv%S(i,j,1)
496 call generic_tracer_source(tv%T,tv%S,rho_dzt,dzt,hml,g%isd,g%jsd,1,dt,&
498 optics%nbands, optics%max_wavelength_band, optics%sw_pen_band, optics%opacity_band, &
499 internal_heat=tv%internal_heat, &
500 frunoff=g%US%R_to_kg_m3*g%US%Z_to_m*g%US%s_to_T*fluxes%frunoff(:,:), sosga=sosga)
504 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
505 g_tracer=>cs%g_tracer_list
507 if (g_tracer_is_prog(g_tracer))
then
508 do k=1,nk ;
do j=jsc,jec ;
do i=isc,iec
509 h_work(i,j,k) = h_old(i,j,k)
510 enddo ;
enddo ;
enddo
512 fluxes, h_work, evap_cfl_limit, minimum_forcing_depth)
516 call g_tracer_get_next(g_tracer, g_tracer_next)
517 if (.NOT.
associated(g_tracer_next))
exit
518 g_tracer=>g_tracer_next
527 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
529 call generic_tracer_vertdiff_g(h_work, ea, eb, dt, gv%kg_m2_to_H, gv%m_to_H, 1)
532 call generic_tracer_vertdiff_g(h_old, ea, eb, dt, gv%kg_m2_to_H, gv%m_to_H, 1)
542 #ifdef _USE_MOM6_DIAG
543 call g_tracer_set_csdiag(cs%diag)
546 end subroutine mom_generic_tracer_column_physics
553 function mom_generic_tracer_stock(h, stocks, G, GV, CS, names, units, stock_index)
554 type(ocean_grid_type),
intent(in) :: G
555 type(verticalGrid_type),
intent(in) :: GV
556 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
557 real,
dimension(:),
intent(out) :: stocks
559 type(MOM_generic_tracer_CS),
pointer :: CS
560 character(len=*),
dimension(:),
intent(out) :: names
561 character(len=*),
dimension(:),
intent(out) :: units
562 integer,
optional,
intent(in) :: stock_index
564 integer :: MOM_generic_tracer_stock
568 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
569 real,
dimension(:,:,:,:),
pointer :: tr_field
570 real,
dimension(:,:,:),
pointer :: tr_ptr
571 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_stock'
573 integer :: i, j, k, is, ie, js, je, nz, m
574 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
576 mom_generic_tracer_stock = 0
577 if (.not.
associated(cs))
return
579 if (
present(stock_index))
then ;
if (stock_index > 0)
then
586 if (.NOT.
associated(cs%g_tracer_list))
return
588 m=1 ; g_tracer=>cs%g_tracer_list
590 call g_tracer_get_alias(g_tracer,names(m))
591 call g_tracer_get_values(g_tracer,names(m),
'units',units(m))
592 units(m) = trim(units(m))//
" kg"
593 call g_tracer_get_pointer(g_tracer,names(m),
'field',tr_field)
596 tr_ptr => tr_field(:,:,:,1)
597 do k=1,nz ;
do j=js,je ;
do i=is,ie
598 stocks(m) = stocks(m) + tr_ptr(i,j,k) * &
599 (g%mask2dT(i,j) * g%US%L_to_m**2*g%areaT(i,j) * h(i,j,k))
600 enddo ;
enddo ;
enddo
601 stocks(m) = gv%H_to_kg_m2 * stocks(m)
604 call g_tracer_get_next(g_tracer, g_tracer_next)
605 if (.NOT.
associated(g_tracer_next))
exit
606 g_tracer=>g_tracer_next
610 mom_generic_tracer_stock = m
612 end function mom_generic_tracer_stock
617 function mom_generic_tracer_min_max(ind_start, got_minmax, gmin, gmax, xgmin, ygmin, zgmin, &
618 xgmax, ygmax, zgmax , G, CS, names, units)
619 use mpp_utilities_mod,
only: mpp_array_global_min_max
620 integer,
intent(in) :: ind_start
621 logical,
dimension(:),
intent(out) :: got_minmax
623 real,
dimension(:),
intent(out) :: gmin
625 real,
dimension(:),
intent(out) :: gmax
627 real,
dimension(:),
intent(out) :: xgmin
628 real,
dimension(:),
intent(out) :: ygmin
629 real,
dimension(:),
intent(out) :: zgmin
630 real,
dimension(:),
intent(out) :: xgmax
631 real,
dimension(:),
intent(out) :: ygmax
632 real,
dimension(:),
intent(out) :: zgmax
633 type(ocean_grid_type),
intent(in) :: G
634 type(MOM_generic_tracer_CS),
pointer :: CS
635 character(len=*),
dimension(:),
intent(out) :: names
636 character(len=*),
dimension(:),
intent(out) :: units
637 integer :: MOM_generic_tracer_min_max
641 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
642 real,
dimension(:,:,:,:),
pointer :: tr_field
643 real,
dimension(:,:,:),
pointer :: tr_ptr
644 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_min_max'
646 real,
dimension(:,:,:),
pointer :: grid_tmask
647 integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau
649 integer :: i, j, k, is, ie, js, je, nz, m
650 real,
allocatable,
dimension(:) :: geo_z
652 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
654 mom_generic_tracer_min_max = 0
655 if (.not.
associated(cs))
return
657 if (.NOT.
associated(cs%g_tracer_list))
return
660 call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask)
665 do k=1,nk ; geo_z(k) = real(k) ;
enddo
667 m=ind_start ; g_tracer=>cs%g_tracer_list
669 call g_tracer_get_alias(g_tracer,names(m))
670 call g_tracer_get_values(g_tracer,names(m),
'units',units(m))
671 units(m) = trim(units(m))//
" kg"
672 call g_tracer_get_pointer(g_tracer,names(m),
'field',tr_field)
677 tr_ptr => tr_field(:,:,:,1)
679 call mpp_array_global_min_max(tr_ptr, grid_tmask,isd,jsd,isc,iec,jsc,jec,nk , gmin(m), gmax(m), &
680 g%geoLonT,g%geoLatT,geo_z,xgmin(m), ygmin(m), zgmin(m), &
681 xgmax(m), ygmax(m), zgmax(m))
683 got_minmax(m) = .true.
686 call g_tracer_get_next(g_tracer, g_tracer_next)
687 if (.NOT.
associated(g_tracer_next))
exit
688 g_tracer=>g_tracer_next
692 mom_generic_tracer_min_max = m
694 end function mom_generic_tracer_min_max
702 subroutine mom_generic_tracer_surface_state(state, h, G, CS)
703 type(ocean_grid_type),
intent(in) :: G
704 type(surface),
intent(inout) :: state
706 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
707 type(MOM_generic_tracer_CS),
pointer :: CS
712 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_surface_state'
713 real,
dimension(G%isd:G%ied,G%jsd:G%jed,1:G%ke,1) :: rho0
714 real,
dimension(G%isd:G%ied,G%jsd:G%jed,1:G%ke) :: dzt
715 type(g_tracer_type),
pointer :: g_tracer
721 dzt(:,:,:) = cs%H_to_m * h(:,:,:)
725 call generic_tracer_coupler_set(state%tr_fields,&
729 ilb=g%isd, jlb=g%jsd,&
742 end subroutine mom_generic_tracer_surface_state
745 subroutine mom_generic_flux_init(verbosity)
746 integer,
optional,
intent(in) :: verbosity
749 character(len=fm_string_len) :: g_tracer_name,longname, package,units,old_package,file_in,file_out
750 real :: const_init_value
751 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_flux_init'
752 type(g_tracer_type),
pointer :: g_tracer_list,g_tracer,g_tracer_next
754 if (.not. g_registered)
then
755 call generic_tracer_register
756 g_registered = .true.
759 call generic_tracer_get_list(g_tracer_list)
760 if (.NOT.
associated(g_tracer_list))
then
761 call mpp_error(warning, trim(sub_name)//
": No generic tracer in the list.")
765 g_tracer=>g_tracer_list
768 call g_tracer_flux_init(g_tracer)
771 call g_tracer_get_next(g_tracer, g_tracer_next)
772 if (.NOT.
associated(g_tracer_next))
exit
773 g_tracer=>g_tracer_next
777 end subroutine mom_generic_flux_init
779 subroutine mom_generic_tracer_fluxes_accumulate(flux_tmp, weight)
780 type(forcing),
intent(in) :: flux_tmp
782 real,
intent(in) :: weight
784 call generic_tracer_coupler_accumulate(flux_tmp%tr_fluxes, weight)
786 end subroutine mom_generic_tracer_fluxes_accumulate
789 subroutine mom_generic_tracer_get(name,member,array, CS)
790 character(len=*),
intent(in) :: name
791 character(len=*),
intent(in) :: member
792 real,
dimension(:,:,:),
intent(out) :: array
793 type(MOM_generic_tracer_CS),
pointer :: CS
795 real,
dimension(:,:,:),
pointer :: array_ptr
796 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_get'
798 call g_tracer_get_pointer(cs%g_tracer_list,name,member,array_ptr)
799 array(:,:,:) = array_ptr(:,:,:)
801 end subroutine mom_generic_tracer_get
804 subroutine end_mom_generic_tracer(CS)
805 type(MOM_generic_tracer_CS),
pointer :: CS
807 call generic_tracer_end
809 if (
associated(cs))
then
812 end subroutine end_mom_generic_tracer
814 #endif /* _USE_GENERIC_TRACER */