Skip to content

Commit

Permalink
(*)+Use reproducing stocks for all tracer packages
Browse files Browse the repository at this point in the history
  Modified the remaining tracer packages to use the reproducing stocks.  The
reported stock values from these packages will have changed slightly, but they
now reproduce across PE layouts.  All solutions are bitwise identical, but
output changes.
  • Loading branch information
Hallberg-NOAA authored and marshallward committed Feb 26, 2022
1 parent 1bf8220 commit a0d0238
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 211 deletions.
25 changes: 7 additions & 18 deletions src/tracer/MOM_CFC_cap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module MOM_CFC_cap

! This file is part of MOM6. See LICENSE.md for the license.

use MOM_coms, only : EFP_type
use MOM_diag_mediator, only : diag_ctrl, register_diag_field, post_data
use MOM_error_handler, only : MOM_error, FATAL, WARNING
use MOM_file_parser, only : get_param, log_param, log_version, param_file_type
Expand All @@ -14,6 +15,7 @@ module MOM_CFC_cap
use MOM_io, only : vardesc, var_desc, query_vardesc, stdout
use MOM_open_boundary, only : ocean_OBC_type
use MOM_restart, only : query_initialized, MOM_restart_CS
use MOM_spatial_means, only : global_mass_int_EFP
use MOM_time_manager, only : time_type
use time_interp_external_mod, only : init_external_field, time_interp_external
use MOM_tracer_registry, only : register_tracer, tracer_registry_type
Expand Down Expand Up @@ -341,14 +343,13 @@ end subroutine CFC_cap_column_physics
!> Calculates the mass-weighted integral of all tracer stocks,
!! returning the number of stocks it has calculated. If the stock_index
!! is present, only the stock corresponding to that coded index is returned.
function CFC_cap_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
function CFC_cap_stock(h, stocks, G, GV, CS, names, units, stock_index)
type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2].
real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each
!! tracer, in kg times concentration units [kg conc].
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
type(EFP_type), dimension(:), intent(out) :: stocks !< The mass-weighted integrated amount of each
!! tracer, in kg times concentration units [kg conc]
type(CFC_cap_CS), pointer :: CS !< The control structure returned by a
!! previous call to register_CFC_cap.
character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated.
Expand All @@ -357,11 +358,6 @@ function CFC_cap_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
!! stock being sought.
integer :: CFC_cap_stock !< The number of stocks calculated here.

! Local variables
real :: stock_scale ! The dimensional scaling factor to convert stocks to kg [kg H-1 L-2 ~> kg m-3 or 1]
real :: mass ! The cell volume or mass [H L2 ~> m3 or kg]
integer :: i, j, k, is, ie, js, je, nz
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke

CFC_cap_stock = 0
if (.not.associated(CS)) return
Expand All @@ -377,15 +373,8 @@ function CFC_cap_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
call query_vardesc(CS%CFC12_desc, name=names(2), units=units(2), caller="CFC_cap_stock")
units(1) = trim(units(1))//" kg" ; units(2) = trim(units(2))//" kg"

stock_scale = US%L_to_m**2 * GV%H_to_kg_m2
stocks(1) = 0.0 ; stocks(2) = 0.0
do k=1,nz ; do j=js,je ; do i=is,ie
mass = G%mask2dT(i,j) * G%areaT(i,j) * h(i,j,k)
stocks(1) = stocks(1) + CS%CFC11(i,j,k) * mass
stocks(2) = stocks(2) + CS%CFC12(i,j,k) * mass
enddo ; enddo ; enddo
stocks(1) = stock_scale * stocks(1)
stocks(2) = stock_scale * stocks(2)
stocks(1) = global_mass_int_EFP(h, G, GV, CS%CFC11, on_PE_only=.true.)
stocks(2) = global_mass_int_EFP(h, G, GV, CS%CFC12, on_PE_only=.true.)

CFC_cap_stock = 2

Expand Down
60 changes: 25 additions & 35 deletions src/tracer/MOM_OCMIP2_CFC.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,28 @@ module MOM_OCMIP2_CFC

! This file is part of MOM6. See LICENSE.md for the license.

use MOM_coupler_types, only : extract_coupler_type_data, set_coupler_type_data
use MOM_coupler_types, only : atmos_ocn_coupler_flux
use MOM_diag_mediator, only : diag_ctrl
use MOM_error_handler, only : MOM_error, FATAL, WARNING
use MOM_file_parser, only : get_param, log_param, log_version, param_file_type
use MOM_forcing_type, only : forcing
use MOM_hor_index, only : hor_index_type
use MOM_grid, only : ocean_grid_type
use MOM_io, only : file_exists, MOM_read_data, slasher, vardesc, var_desc, query_vardesc
use MOM_open_boundary, only : ocean_OBC_type
use MOM_restart, only : query_initialized, MOM_restart_CS
use MOM_sponge, only : set_up_sponge_field, sponge_CS
use MOM_time_manager, only : time_type
use MOM_coms, only : EFP_type
use MOM_coupler_types, only : extract_coupler_type_data, set_coupler_type_data
use MOM_coupler_types, only : atmos_ocn_coupler_flux
use MOM_diag_mediator, only : diag_ctrl
use MOM_error_handler, only : MOM_error, FATAL, WARNING
use MOM_file_parser, only : get_param, log_param, log_version, param_file_type
use MOM_forcing_type, only : forcing
use MOM_hor_index, only : hor_index_type
use MOM_grid, only : ocean_grid_type
use MOM_io, only : file_exists, MOM_read_data, slasher
use MOM_io, only : vardesc, var_desc, query_vardesc
use MOM_open_boundary, only : ocean_OBC_type
use MOM_restart, only : query_initialized, MOM_restart_CS
use MOM_spatial_means, only : global_mass_int_EFP
use MOM_sponge, only : set_up_sponge_field, sponge_CS
use MOM_time_manager, only : time_type
use MOM_tracer_registry, only : register_tracer, tracer_registry_type
use MOM_tracer_diabatic, only : tracer_vertdiff, applyTracerBoundaryFluxesInOut
use MOM_tracer_Z_init, only : tracer_Z_init
use MOM_unit_scaling, only : unit_scale_type
use MOM_variables, only : surface
use MOM_verticalGrid, only : verticalGrid_type
use MOM_tracer_Z_init, only : tracer_Z_init
use MOM_unit_scaling, only : unit_scale_type
use MOM_variables, only : surface
use MOM_verticalGrid, only : verticalGrid_type

implicit none ; private

Expand Down Expand Up @@ -478,14 +481,13 @@ end subroutine OCMIP2_CFC_column_physics
!> This function calculates the mass-weighted integral of all tracer stocks,
!! returning the number of stocks it has calculated. If the stock_index
!! is present, only the stock corresponding to that coded index is returned.
function OCMIP2_CFC_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
function OCMIP2_CFC_stock(h, stocks, G, GV, CS, names, units, stock_index)
type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2].
real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each
!! tracer, in kg times concentration units [kg conc].
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
type(EFP_type), dimension(:), intent(out) :: stocks !< The mass-weighted integrated amount of each
!! tracer, in kg times concentration units [kg conc]
type(OCMIP2_CFC_CS), pointer :: CS !< The control structure returned by a
!! previous call to register_OCMIP2_CFC.
character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated.
Expand All @@ -494,11 +496,6 @@ function OCMIP2_CFC_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
!! stock being sought.
integer :: OCMIP2_CFC_stock !< The number of stocks calculated here.

! Local variables
real :: stock_scale ! The dimensional scaling factor to convert stocks to kg [kg H-1 L-2 ~> kg m-3 or 1]
real :: mass ! The cell volume or mass [H L2 ~> m3 or kg]
integer :: i, j, k, is, ie, js, je, nz
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke

OCMIP2_CFC_stock = 0
if (.not.associated(CS)) return
Expand All @@ -514,15 +511,8 @@ function OCMIP2_CFC_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
call query_vardesc(CS%CFC12_desc, name=names(2), units=units(2), caller="OCMIP2_CFC_stock")
units(1) = trim(units(1))//" kg" ; units(2) = trim(units(2))//" kg"

stock_scale = US%L_to_m**2 * GV%H_to_kg_m2
stocks(1) = 0.0 ; stocks(2) = 0.0
do k=1,nz ; do j=js,je ; do i=is,ie
mass = G%mask2dT(i,j) * G%areaT(i,j) * h(i,j,k)
stocks(1) = stocks(1) + CS%CFC11(i,j,k) * mass
stocks(2) = stocks(2) + CS%CFC12(i,j,k) * mass
enddo ; enddo ; enddo
stocks(1) = stock_scale * stocks(1)
stocks(2) = stock_scale * stocks(2)
stocks(1) = global_mass_int_EFP(h, G, GV, CS%CFC11, on_PE_only=.true.)
stocks(2) = global_mass_int_EFP(h, G, GV, CS%CFC12, on_PE_only=.true.)

OCMIP2_CFC_stock = 2

Expand Down
22 changes: 7 additions & 15 deletions src/tracer/MOM_generic_tracer.F90
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module MOM_generic_tracer
use g_tracer_utils, only: g_tracer_get_pointer,g_tracer_get_alias,g_tracer_set_csdiag

use MOM_ALE_sponge, only : set_up_ALE_sponge_field, ALE_sponge_CS
use MOM_coms, only : max_across_PEs, min_across_PEs, PE_here
use MOM_coms, only : EFP_type, max_across_PEs, min_across_PEs, PE_here
use MOM_diag_mediator, only : post_data, register_diag_field, safe_alloc_ptr
use MOM_diag_mediator, only : diag_ctrl, get_diag_time_end
use MOM_error_handler, only : MOM_error, FATAL, WARNING, NOTE, is_root_pe
Expand All @@ -40,7 +40,7 @@ module MOM_generic_tracer
use MOM_io, only : file_exists, MOM_read_data, slasher
use MOM_open_boundary, only : ocean_OBC_type
use MOM_restart, only : register_restart_field, query_initialized, MOM_restart_CS
use MOM_spatial_means, only : global_area_mean
use MOM_spatial_means, only : global_area_mean, global_mass_int_EFP
use MOM_sponge, only : set_up_sponge_field, sponge_CS
use MOM_time_manager, only : time_type, set_time
use MOM_tracer_diabatic, only : tracer_vertdiff, applyTracerBoundaryFluxesInOut
Expand Down Expand Up @@ -568,13 +568,12 @@ end subroutine MOM_generic_tracer_column_physics
!! being requested specifically, returning the number of stocks it has
!! calculated. If the stock_index is present, only the stock corresponding
!! to that coded index is returned.
function MOM_generic_tracer_stock(h, stocks, G, GV, US, CS, names, units, stock_index)
function MOM_generic_tracer_stock(h, stocks, G, GV, CS, names, units, stock_index)
type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure
type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]
real, dimension(:), intent(out) :: stocks !< The mass-weighted integrated amount of each
!! tracer, in kg times concentration units [kg conc].
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
type(EFP_type), dimension(:), intent(out) :: stocks !< The mass-weighted integrated amount of each
!! tracer, in kg times concentration units [kg conc]
type(MOM_generic_tracer_CS), pointer :: CS !< Pointer to the control structure for this module.
character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated.
character(len=*), dimension(:), intent(out) :: units !< The units of the stocks calculated.
Expand All @@ -584,14 +583,12 @@ function MOM_generic_tracer_stock(h, stocks, G, GV, US, CS, names, units, stock_
!! number of stocks calculated here.

! Local variables
real :: stock_scale ! The dimensional scaling factor to convert stocks to kg [kg H-1 L-2 ~> kg m-3 or 1]
type(g_tracer_type), pointer :: g_tracer, g_tracer_next
real, dimension(:,:,:,:), pointer :: tr_field
real, dimension(:,:,:), pointer :: tr_ptr
character(len=128), parameter :: sub_name = 'MOM_generic_tracer_stock'

integer :: i, j, k, is, ie, js, je, nz, m
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
integer :: m

MOM_generic_tracer_stock = 0
if (.not.associated(CS)) return
Expand All @@ -605,20 +602,15 @@ function MOM_generic_tracer_stock(h, stocks, G, GV, US, CS, names, units, stock_

if (.NOT. associated(CS%g_tracer_list)) return ! No stocks.

stock_scale = US%L_to_m**2 * GV%H_to_kg_m2
m=1 ; g_tracer=>CS%g_tracer_list
do
call g_tracer_get_alias(g_tracer,names(m))
call g_tracer_get_values(g_tracer,names(m),'units',units(m))
units(m) = trim(units(m))//" kg"
call g_tracer_get_pointer(g_tracer,names(m),'field',tr_field)

stocks(m) = 0.0
tr_ptr => tr_field(:,:,:,1)
do k=1,nz ; do j=js,je ; do i=is,ie
stocks(m) = stocks(m) + tr_ptr(i,j,k) * (G%mask2dT(i,j) * G%areaT(i,j) * h(i,j,k))
enddo ; enddo ; enddo
stocks(m) = stock_scale * stocks(m)
stocks(m) = global_mass_int_EFP(h, G, GV, tr_ptr, on_PE_only=.true.)

!traverse the linked list till hit NULL
call g_tracer_get_next(g_tracer, g_tracer_next)
Expand Down
29 changes: 9 additions & 20 deletions src/tracer/MOM_tracer_flow_control.F90
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, US, CS, stock_names, stock
! Local variables
character(len=200), dimension(MAX_FIELDS_) :: names, units
character(len=200) :: set_pkg_name
real, dimension(MAX_FIELDS_) :: values
! real, dimension(MAX_FIELDS_) :: values
type(EFP_type), dimension(MAX_FIELDS_) :: values_EFP
type(EFP_type), dimension(MAX_FIELDS_) :: stock_val_EFP
integer :: max_ns, ns_tot, ns, index, pkg, max_pkgs, nn, n
Expand All @@ -628,9 +628,8 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, US, CS, stock_names, stock

! Add other user-provided calls here.
if (CS%use_USER_tracer_example) then
ns = USER_tracer_stock(h, values, G, GV, US, CS%USER_tracer_example_CSp, &
ns = USER_tracer_stock(h, values_EFP, G, GV, CS%USER_tracer_example_CSp, &
names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
call store_stocks("tracer_example", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif
Expand All @@ -644,34 +643,27 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, US, CS, stock_names, stock
if (CS%use_ideal_age) then
ns = ideal_age_stock(h, values_EFP, G, GV, CS%ideal_age_tracer_CSp, &
names, units, stock_index)
! do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
call store_stocks("ideal_age_example", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif
if (CS%use_regional_dyes) then
ns = dye_stock(h, values, G, GV, US, CS%dye_tracer_CSp, &
names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
ns = dye_stock(h, values_EFP, G, GV, CS%dye_tracer_CSp, names, units, stock_index)
call store_stocks("regional_dyes", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif
if (CS%use_oil) then
ns = oil_stock(h, values, G, GV, US, CS%oil_tracer_CSp, &
names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
ns = oil_stock(h, values_EFP, G, GV, CS%oil_tracer_CSp, names, units, stock_index)
call store_stocks("oil_tracer", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif
if (CS%use_OCMIP2_CFC) then
ns = OCMIP2_CFC_stock(h, values, G, GV, US, CS%OCMIP2_CFC_CSp, names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
ns = OCMIP2_CFC_stock(h, values_EFP, G, GV, CS%OCMIP2_CFC_CSp, names, units, stock_index)
call store_stocks("MOM_OCMIP2_CFC", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif

if (CS%use_CFC_cap) then
ns = CFC_cap_stock(h, values, G, GV, US, CS%CFC_cap_CSp, names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
ns = CFC_cap_stock(h, values_EFP, G, GV, CS%CFC_cap_CSp, names, units, stock_index)
call store_stocks("MOM_CFC_cap", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif
Expand All @@ -685,9 +677,8 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, US, CS, stock_names, stock
endif

if (CS%use_MOM_generic_tracer) then
ns = MOM_generic_tracer_stock(h, values, G, GV, US, CS%MOM_generic_tracer_CSp, &
ns = MOM_generic_tracer_stock(h, values_EFP, G, GV, CS%MOM_generic_tracer_CSp, &
names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
call store_stocks("MOM_generic_tracer", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
nn=ns_tot-ns+1
Expand All @@ -697,17 +688,15 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, US, CS, stock_names, stock

endif
if (CS%use_pseudo_salt_tracer) then
ns = pseudo_salt_stock(h, values, G, GV, US, CS%pseudo_salt_tracer_CSp, &
ns = pseudo_salt_stock(h, values_EFP, G, GV, CS%pseudo_salt_tracer_CSp, &
names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
call store_stocks("pseudo_salt_tracer", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif

if (CS%use_boundary_impulse_tracer) then
ns = boundary_impulse_stock(h, values, G, GV, US, CS%boundary_impulse_tracer_CSp, &
ns = boundary_impulse_stock(h, values_EFP, G, GV, CS%boundary_impulse_tracer_CSp, &
names, units, stock_index)
do n=1,ns ; values_EFP(n) = real_to_EFP(values(n)) ; enddo
call store_stocks("boundary_impulse_tracer", ns, names, units, values_EFP, index, stock_val_EFP, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
endif
Expand Down
Loading

0 comments on commit a0d0238

Please sign in to comment.