32 #include <MOM_memory.h> 36 #ifdef _USE_GENERIC_TRACER 37 #include <fms_platform.h> 39 use mpp_mod
, only: stdout, mpp_error, fatal,warning,note
40 use field_manager_mod
, only: fm_get_index,fm_string_len
42 use generic_tracer
, only: generic_tracer_register, generic_tracer_get_diag_list
43 use generic_tracer
, only: generic_tracer_init, generic_tracer_source, generic_tracer_register_diag
44 use generic_tracer
, only: generic_tracer_coupler_get, generic_tracer_coupler_set
45 use generic_tracer
, only: generic_tracer_end, generic_tracer_get_list, do_generic_tracer
46 use generic_tracer
, only: generic_tracer_update_from_bottom,generic_tracer_vertdiff_g
47 use generic_tracer
, only: generic_tracer_coupler_accumulate
49 use g_tracer_utils
, only: g_tracer_get_name,g_tracer_set_values,g_tracer_set_common,g_tracer_get_common
50 use g_tracer_utils
, only: g_tracer_get_next,g_tracer_type,g_tracer_is_prog,g_tracer_flux_init
51 use g_tracer_utils
, only: g_tracer_send_diag,g_tracer_get_values
52 use g_tracer_utils
, only: g_tracer_get_pointer,g_tracer_get_alias,g_diag_type,g_tracer_set_csdiag
72 use mom_tracer_initialization_from_z
, only : mom_initialize_tracer_from_z
78 implicit none ;
private 79 logical :: g_registered = .false.
81 public register_mom_generic_tracer, initialize_mom_generic_tracer
82 public mom_generic_tracer_column_physics, mom_generic_tracer_surface_state
83 public end_mom_generic_tracer, mom_generic_tracer_get
84 public mom_generic_tracer_stock
85 public mom_generic_flux_init
86 public mom_generic_tracer_min_max
87 public mom_generic_tracer_fluxes_accumulate
89 type,
public :: mom_generic_tracer_cs ;
private 90 character(len = 200) :: ic_file
93 real :: tracer_ic_val = 0.0
94 real :: tracer_land_val = -1.0
95 logical :: tracers_may_reinit
105 type(g_tracer_type),
pointer :: g_tracer_list => null()
108 type(g_diag_type),
pointer :: g_diag_list => null()
112 end type mom_generic_tracer_cs
115 #include "version_variable.h" 134 function register_mom_generic_tracer(HI, GV, param_file, CS, tr_Reg, restart_CS)
138 type(mom_generic_tracer_cs),
pointer :: cs
152 logical :: register_mom_generic_tracer
155 character(len=fm_string_len),
parameter :: sub_name =
'register_MOM_generic_tracer' 156 character(len=200) :: inputdir
159 integer :: ntau, k,i,j,axes(3)
160 type(g_tracer_type),
pointer :: g_tracer,g_tracer_next
161 character(len=fm_string_len) :: g_tracer_name,longname,units
162 real,
dimension(:,:,:,:),
pointer :: tr_field
163 real,
dimension(:,:,:),
pointer :: tr_ptr
164 real,
dimension(HI%isd:HI%ied, HI%jsd:HI%jed,GV%ke) :: grid_tmask
165 integer,
dimension(HI%isd:HI%ied, HI%jsd:HI%jed) :: grid_kmt
168 register_mom_generic_tracer = .false.
169 if (
associated(cs))
then 170 call mpp_error(warning,
"register_MOM_generic_tracer called with an "// &
171 "associated control structure.")
179 if (.not. g_registered)
then 180 call generic_tracer_register
181 g_registered = .true.
186 call log_version(param_file, sub_name, version,
"")
187 call get_param(param_file, sub_name,
"GENERIC_TRACER_IC_FILE", cs%IC_file, &
188 "The file in which the generic trcer initial values can \n"//&
189 "be found, or an empty string for internal initialization.", &
191 if ((len_trim(cs%IC_file) > 0) .and. (scan(cs%IC_file,
'/') == 0))
then 193 call get_param(param_file, sub_name,
"INPUTDIR", inputdir, default=
".")
194 cs%IC_file = trim(slasher(inputdir))//trim(cs%IC_file)
195 call log_param(param_file, sub_name,
"INPUTDIR/GENERIC_TRACER_IC_FILE", cs%IC_file)
197 call get_param(param_file, sub_name,
"GENERIC_TRACER_IC_FILE_IS_Z", cs%Z_IC_file, &
198 "If true, GENERIC_TRACER_IC_FILE is in depth space, not \n"//&
199 "layer space.",default=.false.)
200 call get_param(param_file, sub_name,
"TRACERS_MAY_REINIT", cs%tracers_may_reinit, &
201 "If true, tracers may go through the initialization code \n"//&
202 "if they are not found in the restart files. Otherwise \n"//&
203 "it is a fatal error if tracers are not found in the \n"//&
204 "restart files of a restarted run.", default=.false.)
206 cs%restart_CSp => restart_cs
216 grid_tmask(:,:,:) = 0.0
223 call generic_tracer_init(hi%isc,hi%iec,hi%jsc,hi%jec,hi%isd,hi%ied,hi%jsd,hi%jed,&
224 gv%ke,ntau,axes,grid_tmask,grid_kmt,set_time(0,0))
232 call generic_tracer_get_list(cs%g_tracer_list)
233 if(.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal, trim(sub_name)//&
234 ": No tracer in the list.")
237 g_tracer=>cs%g_tracer_list
239 call g_tracer_get_alias(g_tracer,g_tracer_name)
241 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'field',tr_field)
242 call g_tracer_get_values(g_tracer,g_tracer_name,
'longname', longname)
243 call g_tracer_get_values(g_tracer,g_tracer_name,
'units',units )
246 vdesc =
var_desc(g_tracer_name, units, longname, &
247 caller=
"MOM_generic_tracer")
249 tr_ptr => tr_field(:,:,:,1)
261 if (g_tracer_is_prog(g_tracer)) &
262 call register_tracer(tr_ptr, vdesc, param_file, hi, gv, tr_reg)
265 call g_tracer_get_next(g_tracer, g_tracer_next)
266 if(.NOT.
associated(g_tracer_next))
exit 267 g_tracer=>g_tracer_next
271 register_mom_generic_tracer = .true.
272 end function register_mom_generic_tracer
288 subroutine initialize_mom_generic_tracer(restart, day, G, GV, h, param_file, diag, OBC, CS, &
289 sponge_CSp, ALE_sponge_CSp,diag_to_Z_CSp)
290 logical,
intent(in) :: restart
291 type(time_type),
target,
intent(in) :: day
294 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
296 type(
diag_ctrl),
target,
intent(in) :: diag
298 type(mom_generic_tracer_cs),
pointer :: cs
322 character(len=fm_string_len),
parameter :: sub_name =
'initialize_MOM_generic_tracer' 324 integer :: i, j, k, isc, iec, jsc, jec, nk
325 type(g_tracer_type),
pointer :: g_tracer,g_tracer_next
326 type(g_diag_type) ,
pointer :: g_diag,g_diag_next
327 character(len=fm_string_len) :: g_tracer_name, longname, units
328 real,
dimension(:,:,:,:),
pointer :: tr_field
329 real,
dimension(:,:,:),
pointer :: tr_ptr
330 real,
dimension(G%isd:G%ied, G%jsd:G%jed,1:G%ke) :: grid_tmask
331 integer,
dimension(G%isd:G%ied, G%jsd:G%jed) :: grid_kmt
337 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec ; nk = g%ke
341 if(.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal, trim(sub_name)//&
342 ": No tracer in the list.")
344 g_tracer=>cs%g_tracer_list
347 if(index(cs%IC_file,
'_NULL_') .ne. 0)
then 348 call mom_error(warning,
"The name of the IC_file "//trim(cs%IC_file)//&
349 " indicates no MOM initialization was asked for the generic tracers."//&
350 "Bypassing the MOM initialization of ALL generic tracers!")
353 call g_tracer_get_alias(g_tracer,g_tracer_name)
354 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'field',tr_field)
355 tr_ptr => tr_field(:,:,:,1)
357 if (.not.restart .or. (cs%tracers_may_reinit .and. &
360 if(g_tracer%requires_src_info )
then 361 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
362 "initializing generic tracer "//trim(g_tracer_name)//&
363 " using MOM_initialize_tracer_from_Z ")
365 call mom_initialize_tracer_from_z(h, tr_ptr, g, gv, param_file, &
366 src_file = g_tracer%src_file, &
367 src_var_nam = g_tracer%src_var_name, &
368 src_var_unit_conversion = g_tracer%src_var_unit_conversion,&
369 src_var_record = g_tracer%src_var_record, &
370 src_var_gridspec = g_tracer%src_var_gridspec )
373 do k=1,nk ;
do j=jsc,jec ;
do i=isc,iec
374 if(tr_ptr(i,j,k) .ne. cs%tracer_land_val)
then 375 if(tr_ptr(i,j,k) .lt. g_tracer%src_var_valid_min) tr_ptr(i,j,k) = g_tracer%src_var_valid_min
382 if(trim(g_tracer_name) .eq.
'cased')
then 383 do k=2,nk ;
do j=jsc,jec ;
do i=isc,iec
384 if(tr_ptr(i,j,k) .ne. cs%tracer_land_val)
then 392 if (len_trim(cs%IC_file) > 0)
then 394 if (.not.file_exists(cs%IC_file))
call mom_error(fatal, &
395 "initialize_MOM_Generic_tracer: Unable to open "//cs%IC_file)
396 if (cs%Z_IC_file)
then 397 ok = tracer_z_init(tr_ptr, h, cs%IC_file, g_tracer_name, g)
399 ok = tracer_z_init(tr_ptr, h, cs%IC_file, trim(g_tracer_name), g)
400 if (.not.ok)
call mom_error(fatal,
"initialize_MOM_Generic_tracer: "//&
401 "Unable to read "//trim(g_tracer_name)//
" from "//&
402 trim(cs%IC_file)//
".")
404 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
405 "initialized generic tracer "//trim(g_tracer_name)//&
406 " using Generic Tracer File on Z: "//cs%IC_file)
409 call mom_error(note,
"initialize_MOM_generic_tracer: "//&
410 "Using Generic Tracer IC file on native grid "//trim(cs%IC_file)//&
411 " for tracer "//trim(g_tracer_name))
412 call read_data(cs%IC_file, trim(g_tracer_name), tr_ptr, domain=g%Domain%mpp_domain)
415 call mom_error(fatal,
"initialize_MOM_generic_tracer: "//&
416 "check Generic Tracer IC filename "//trim(cs%IC_file)//
".")
423 call g_tracer_get_next(g_tracer, g_tracer_next)
424 if(.NOT.
associated(g_tracer_next))
exit 425 g_tracer=>g_tracer_next
433 grid_tmask(:,:,:) = 0.0
435 do j = g%jsd, g%jed ;
do i = g%isd, g%ied
436 if (g%mask2dT(i,j) .gt. 0)
then 437 grid_tmask(i,j,:) = 1.0
441 call g_tracer_set_common(g%isc,g%iec,g%jsc,g%jec,g%isd,g%ied,g%jsd,g%jed,&
442 gv%ke,1,cs%diag%axesTL%handles,grid_tmask,grid_kmt,day)
446 #ifdef _USE_MOM6_DIAG 447 call g_tracer_set_csdiag(cs%diag)
449 call generic_tracer_register_diag()
450 #ifdef _USE_MOM6_DIAG 451 call g_tracer_set_csdiag(cs%diag)
457 if(.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal, trim(sub_name)//&
458 ": No tracer in the list.")
460 g_tracer=>cs%g_tracer_list
462 call g_tracer_get_alias(g_tracer,g_tracer_name)
464 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'field',tr_field)
465 tr_ptr => tr_field(:,:,:,1)
466 call g_tracer_get_values(g_tracer,g_tracer_name,
'longname', longname)
467 call g_tracer_get_values(g_tracer,g_tracer_name,
'units',units )
469 call register_z_tracer(tr_ptr, trim(g_tracer_name),longname , units, &
470 day, g, diag_to_z_csp)
473 call g_tracer_get_next(g_tracer, g_tracer_next)
474 if(.NOT.
associated(g_tracer_next))
exit 475 g_tracer=>g_tracer_next
481 call generic_tracer_get_diag_list(cs%g_diag_list)
482 if(
associated(cs%g_diag_list))
then 483 g_diag=>cs%g_diag_list
485 if(g_diag%Z_diag .ne. 0) &
486 call register_z_tracer(g_diag%field_ptr, trim(g_diag%name),g_diag%longname , g_diag%units, &
487 day, g, diag_to_z_csp)
491 if(.NOT.
associated(g_diag))
exit 496 cs%H_to_m = gv%H_to_m
498 end subroutine initialize_mom_generic_tracer
516 subroutine mom_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml, dt, G, GV, CS, tv, optics, &
517 evap_CFL_limit, minimum_forcing_depth)
518 type(ocean_grid_type),
intent(in) :: g
519 type(verticalgrid_type),
intent(in) :: gv
520 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h_old, h_new, ea, eb
521 type(forcing),
intent(in) :: fluxes
522 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: hml
523 real,
intent(in) :: dt
524 type(mom_generic_tracer_cs),
pointer :: cs
525 type(thermo_var_ptrs),
intent(in) :: tv
526 type(optics_type),
intent(in) :: optics
527 real,
optional,
intent(in) :: evap_cfl_limit
528 real,
optional,
intent(in) :: minimum_forcing_depth
556 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_column_physics' 558 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
559 character(len=fm_string_len) :: g_tracer_name
560 real,
dimension(:,:),
pointer :: stf_array,trunoff_array,runoff_tracer_flux_array
562 real :: surface_field(szi_(g),szj_(g))
565 real,
dimension(G%isd:G%ied,G%jsd:G%jed,G%ke) :: rho_dzt, dzt
566 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work
567 integer :: i, j, k, isc, iec, jsc, jec, nk
569 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec ; nk = g%ke
572 if(.NOT.
associated(cs%g_tracer_list))
call mpp_error(fatal,&
573 trim(sub_name)//
": No tracer in the list.")
575 #ifdef _USE_MOM6_DIAG 576 call g_tracer_set_csdiag(cs%diag)
590 g_tracer=>cs%g_tracer_list
592 if(_allocated(g_tracer%trunoff))
then 593 call g_tracer_get_alias(g_tracer,g_tracer_name)
594 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'stf', stf_array)
595 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'trunoff',trunoff_array)
596 call g_tracer_get_pointer(g_tracer,g_tracer_name,
'runoff_tracer_flux',runoff_tracer_flux_array)
598 runoff_tracer_flux_array = trunoff_array * fluxes%lrunoff
599 stf_array = stf_array + runoff_tracer_flux_array
603 call g_tracer_get_next(g_tracer, g_tracer_next)
604 if(.NOT.
associated(g_tracer_next))
exit 605 g_tracer=>g_tracer_next
613 rho_dzt(:,:,:) = gv%H_to_kg_m2 * gv%Angstrom
614 do k = 1, nk ;
do j = jsc, jec ;
do i = isc, iec
615 rho_dzt(i,j,k) = gv%H_to_kg_m2 * h_old(i,j,k)
619 do k = 1, nk ;
do j = jsc, jec ;
do i = isc, iec
620 dzt(i,j,k) = gv%H_to_m * h_old(i,j,k)
623 do j=jsc,jec ;
do i=isc,iec
624 surface_field(i,j) = tv%S(i,j,1)
626 sosga = global_area_mean(surface_field, g)
632 call generic_tracer_source(tv%T,tv%S,rho_dzt,dzt,hml,g%isd,g%jsd,1,dt,&
633 g%areaT,get_diag_time_end(cs%diag),&
634 optics%nbands, optics%max_wavelength_band, optics%sw_pen_band, optics%opacity_band, sosga=sosga)
638 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then 639 g_tracer=>cs%g_tracer_list
641 if (g_tracer_is_prog(g_tracer))
then 642 do k=1,nk ;
do j=jsc,jec ;
do i=isc,iec
643 h_work(i,j,k) = h_old(i,j,k)
644 enddo ;
enddo ; enddo;
645 call applytracerboundaryfluxesinout(g, gv, g_tracer%field(:,:,:,1), dt, fluxes, h_work, &
646 evap_cfl_limit, minimum_forcing_depth)
650 call g_tracer_get_next(g_tracer, g_tracer_next)
651 if(.NOT.
associated(g_tracer_next))
exit 652 g_tracer=>g_tracer_next
661 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then 662 call generic_tracer_vertdiff_g(h_work, ea, eb, dt, gv%kg_m2_to_H, gv%m_to_H, 1)
664 call generic_tracer_vertdiff_g(h_old, ea, eb, dt, gv%kg_m2_to_H, gv%m_to_H, 1)
669 call generic_tracer_update_from_bottom(dt, 1, get_diag_time_end(cs%diag))
672 call g_tracer_send_diag(cs%g_tracer_list, get_diag_time_end(cs%diag), tau=1)
673 #ifdef _USE_MOM6_DIAG 674 call g_tracer_set_csdiag(cs%diag)
678 end subroutine mom_generic_tracer_column_physics
695 function mom_generic_tracer_stock(h, stocks, G, GV, CS, names, units, stock_index)
696 type(ocean_grid_type),
intent(in) :: g
697 type(verticalgrid_type),
intent(in) :: gv
698 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
699 real,
dimension(:),
intent(out) :: stocks
700 type(mom_generic_tracer_cs),
pointer :: cs
701 character(len=*),
dimension(:),
intent(out) :: names
702 character(len=*),
dimension(:),
intent(out) :: units
703 integer,
optional,
intent(in) :: stock_index
704 integer :: mom_generic_tracer_stock
720 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
721 real,
dimension(:,:,:,:),
pointer :: tr_field
722 real,
dimension(:,:,:),
pointer :: tr_ptr
723 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_stock' 725 integer :: i, j, k, is, ie, js, je, nz, m
726 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
728 mom_generic_tracer_stock = 0
729 if (.not.
associated(cs))
return 731 if (
present(stock_index))
then ;
if (stock_index > 0)
then 738 if(.NOT.
associated(cs%g_tracer_list))
return 740 m=1 ; g_tracer=>cs%g_tracer_list
742 call g_tracer_get_alias(g_tracer,names(m))
743 call g_tracer_get_values(g_tracer,names(m),
'units',units(m))
744 units(m) = trim(units(m))//
" kg" 745 call g_tracer_get_pointer(g_tracer,names(m),
'field',tr_field)
748 tr_ptr => tr_field(:,:,:,1)
749 do k=1,nz ;
do j=js,je ;
do i=is,ie
750 stocks(m) = stocks(m) + tr_ptr(i,j,k) * &
751 (g%mask2dT(i,j) * g%areaT(i,j) * h(i,j,k))
752 enddo ;
enddo ;
enddo 753 stocks(m) = gv%H_to_kg_m2 * stocks(m)
756 call g_tracer_get_next(g_tracer, g_tracer_next)
757 if(.NOT.
associated(g_tracer_next))
exit 758 g_tracer=>g_tracer_next
762 mom_generic_tracer_stock = m
764 end function mom_generic_tracer_stock
780 function mom_generic_tracer_min_max(ind_start, got_minmax, gmin, gmax, xgmin, ygmin, zgmin, xgmax, ygmax, zgmax , G, CS, names, units)
781 use mpp_utilities_mod
, only: mpp_array_global_min_max
782 integer,
intent(in) :: ind_start
783 logical,
dimension(:),
intent(out) :: got_minmax
784 real,
dimension(:),
intent(out) :: gmin,gmax
785 real,
dimension(:),
intent(out) :: xgmin, ygmin, zgmin, xgmax, ygmax, zgmax
786 type(ocean_grid_type),
intent(in) :: g
787 type(mom_generic_tracer_cs),
pointer :: cs
788 character(len=*),
dimension(:),
intent(out) :: names
789 character(len=*),
dimension(:),
intent(out) :: units
790 integer :: mom_generic_tracer_min_max
806 type(g_tracer_type),
pointer :: g_tracer, g_tracer_next
807 real,
dimension(:,:,:,:),
pointer :: tr_field
808 real,
dimension(:,:,:),
pointer :: tr_ptr
809 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_min_max' 811 real,
dimension(:,:,:),
pointer :: grid_tmask
812 integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau
814 integer :: i, j, k, is, ie, js, je, nz, m
815 real,
allocatable,
dimension(:) :: geo_z
817 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
819 mom_generic_tracer_min_max = 0
820 if (.not.
associated(cs))
return 822 if(.NOT.
associated(cs%g_tracer_list))
return 825 call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask)
830 do k=1,nk ; geo_z(k) =
real(k) ; enddo
833 m=ind_start ; g_tracer=>cs%g_tracer_list
835 call g_tracer_get_alias(g_tracer,names(m))
836 call g_tracer_get_values(g_tracer,names(m),
'units',units(m))
837 units(m) = trim(units(m))//
" kg" 838 call g_tracer_get_pointer(g_tracer,names(m),
'field',tr_field)
843 tr_ptr => tr_field(:,:,:,1)
846 call mpp_array_global_min_max(tr_ptr, grid_tmask,isd,jsd,isc,iec,jsc,jec,nk , gmin(m), gmax(m), &
847 g%geoLonT,g%geoLatT,geo_z,xgmin(m), ygmin(m), zgmin(m), xgmax(m), ygmax(m), zgmax(m))
849 got_minmax(m) = .true.
853 call g_tracer_get_next(g_tracer, g_tracer_next)
854 if(.NOT.
associated(g_tracer_next))
exit 855 g_tracer=>g_tracer_next
859 mom_generic_tracer_min_max = m
861 end function mom_generic_tracer_min_max
877 subroutine mom_generic_tracer_surface_state(state, h, G, CS)
878 type(ocean_grid_type),
intent(in) :: g
879 type(surface),
intent(inout) :: state
880 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
881 type(mom_generic_tracer_cs),
pointer :: cs
893 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_surface_state' 894 real,
dimension(G%isd:G%ied,G%jsd:G%jed,1:G%ke,1) :: rho0
895 real,
dimension(G%isd:G%ied,G%jsd:G%jed,1:G%ke) :: dzt
896 type(g_tracer_type),
pointer :: g_tracer
902 dzt(:,:,:) = cs%H_to_m * h(:,:,:)
904 sosga = global_area_mean(state%SSS, g)
906 call generic_tracer_coupler_set(state%tr_fields,&
910 ilb=g%isd, jlb=g%jsd,&
912 tau=1,sosga=sosga,model_time=get_diag_time_end(cs%diag))
923 end subroutine mom_generic_tracer_surface_state
926 subroutine mom_generic_flux_init
929 character(len=fm_string_len) :: g_tracer_name,longname, package,units,old_package,file_in,file_out
930 real :: const_init_value
931 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_flux_init' 932 type(g_tracer_type),
pointer :: g_tracer_list,g_tracer,g_tracer_next
934 if (.not. g_registered)
then 935 call generic_tracer_register
936 g_registered = .true.
939 call generic_tracer_get_list(g_tracer_list)
940 if(.NOT.
associated(g_tracer_list))
then 941 call mpp_error(warning, trim(sub_name)//
": No generic tracer in the list.")
945 g_tracer=>g_tracer_list
948 call g_tracer_flux_init(g_tracer)
951 call g_tracer_get_next(g_tracer, g_tracer_next)
952 if(.NOT.
associated(g_tracer_next))
exit 953 g_tracer=>g_tracer_next
957 end subroutine mom_generic_flux_init
959 subroutine mom_generic_tracer_fluxes_accumulate(flux_tmp, weight)
960 type(forcing),
intent(in) :: flux_tmp
961 real,
intent(in) :: weight
963 call generic_tracer_coupler_accumulate(flux_tmp%tr_fluxes, weight)
965 end subroutine mom_generic_tracer_fluxes_accumulate
967 subroutine mom_generic_tracer_get(name,member,array, CS)
968 character(len=*),
intent(in) :: name
969 character(len=*),
intent(in) :: member
970 real,
dimension(:,:,:),
intent(out) :: array
971 type(mom_generic_tracer_cs),
pointer :: cs
975 real,
dimension(:,:,:),
pointer :: array_ptr
976 character(len=fm_string_len),
parameter :: sub_name =
'MOM_generic_tracer_get' 978 call g_tracer_get_pointer(cs%g_tracer_list,name,member,array_ptr)
979 array(:,:,:) = array_ptr(:,:,:)
981 end subroutine mom_generic_tracer_get
995 subroutine end_mom_generic_tracer(CS)
996 type(mom_generic_tracer_cs),
pointer :: cs
1002 call generic_tracer_end
1004 if (
associated(cs))
then 1007 end subroutine end_mom_generic_tracer
1009 #endif /* _USE_GENERIC_TRACER */ 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.
logical function, public tracer_z_init(tr, h, filename, tr_name, G, missing_val, land_val)
Ocean grid type. See mom_grid for details.
Provides the ocean grid type.
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.
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...
subroutine, public set_up_sponge_field(sp_val, f_ptr, G, nlay, CS, sp_val_i_mean)
Type to carry basic tracer information.
logical function, public is_root_pe()
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...
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 ...
Type for describing a variable, typically a tracer.
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...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
Controls where open boundary conditions are applied.
real function, public global_area_mean(var, G)
subroutine, public mom_error(level, message, all_print)