Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add KPP nonlocal term to passive tracers #202

Merged
merged 35 commits into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
420a0e6
Add KPP nonlocal term to passive tracers
mnlevy1981 Nov 30, 2021
c0f6f81
Shorten long lines
mnlevy1981 Nov 30, 2021
eaaaa07
Fix build error in OpenMP test
mnlevy1981 Nov 30, 2021
af095e0
Add KPP nonlocal diags for passive tracers
mnlevy1981 Dec 1, 2021
cecb61d
Cleanup to pass doxygen CI test
mnlevy1981 Dec 1, 2021
bd1089a
Refactor MOM_CFC_cap
mnlevy1981 Dec 6, 2021
eb8dfd7
Refactor MOM_CVMix_KPP.F90
mnlevy1981 Dec 7, 2021
80508d9
Add NLT budget contibution to Tr diags
mnlevy1981 Dec 7, 2021
f11f12c
Only define KPP tracer diags when using KPP
mnlevy1981 Dec 7, 2021
882e173
Commit to pass OpenMP tests
mnlevy1981 Dec 7, 2021
f51681b
Can pass tr_ptr to KPP_NonLocalTransport()
mnlevy1981 Dec 8, 2021
fec61e0
Refactor MOM_tracer_registry.F90
mnlevy1981 Dec 9, 2021
301ed51
register_tracer() can return tracer_type pointer
mnlevy1981 Dec 10, 2021
c435aad
Remove declaration of unused variable
mnlevy1981 Dec 10, 2021
9b1f46b
Add KPP nonlocal terms to pseudo-salt tracer
mnlevy1981 Dec 13, 2021
cfe90aa
Tracers call KPP nonlocal before tracer_vertdiff
mnlevy1981 Dec 14, 2021
312743d
pseudo-salt was using wrong salt flux
mnlevy1981 Dec 14, 2021
f9d6247
Rearrange some code computing nonlocal transport
mnlevy1981 Dec 15, 2021
9c9860c
Clean up diagnostics
mnlevy1981 Dec 16, 2021
8aad2c3
Remove use_KPP from tracer_flow_control_CS
mnlevy1981 Dec 16, 2021
45c6b76
Change id_net_surfflux longname
mnlevy1981 Dec 16, 2021
3913856
Let register_tracer set more diag metadata
mnlevy1981 Dec 16, 2021
44885df
Remove use_KPP from MOM control structure
mnlevy1981 Dec 17, 2021
4f7621f
Clean up diag names and scale factors
mnlevy1981 Dec 17, 2021
a7eeab4
Code cleanup following review
mnlevy1981 Dec 20, 2021
59423ac
APPLY_NONLOCAL_TRANSPORT applies to all tracers
mnlevy1981 Jan 14, 2022
124ef06
Remove matrix multiplication from post_data call
mnlevy1981 Jan 20, 2022
ba5d8c4
Cleanup following more code review
mnlevy1981 Jan 25, 2022
89e0746
Break up long lines
mnlevy1981 Jan 25, 2022
d5e9629
Merge branch 'dev/ncar' into extend_KPP_nonlocal
mnlevy1981 Feb 27, 2022
900f6cf
shorten line length to pass CI test
mnlevy1981 Mar 2, 2022
3e4f827
Clean up two comments
mnlevy1981 Mar 2, 2022
728fe16
Remove unused variable from MOM_forcing_type.F90
mnlevy1981 Mar 3, 2022
9fb0643
Rename CFC_tracer_metadata -> CFC_tracer_data
mnlevy1981 Mar 7, 2022
e3d278e
Fix inaccurate comments
mnlevy1981 Mar 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/parameterizations/vertical/MOM_CVMix_KPP.F90
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module MOM_CVMix_KPP
public :: KPP_end
public :: KPP_NonLocalTransport_temp
public :: KPP_NonLocalTransport_saln
public :: KPP_NonLocalTransport_passive_tracers
public :: KPP_get_BLD

! Enumerated constants
Expand Down Expand Up @@ -1501,6 +1502,60 @@ subroutine KPP_NonLocalTransport_saln(CS, G, GV, h, nonLocalTrans, surfFlux, dt,
end subroutine KPP_NonLocalTransport_saln


!> Apply KPP non-local transport of surface fluxes for tracers
!> other than temperature and salinity
subroutine KPP_NonLocalTransport_passive_tracers(applyNonLocalTrans, G, GV, h, nonLocalTrans, surfFlux, &
dt, scalar, scale_factor)

logical, intent(in) :: applyNonLocalTrans !< if True, apply computed
!! term to scalar
type(ocean_grid_type), intent(in) :: G !< Ocean grid
type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer/level thickness [H ~> m or kg m-2]
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: nonLocalTrans !< Non-local transport [nondim]
real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfFlux !< Surface flux of scalar
!! [conc H s-1 ~> conc m s-1 or conc kg m-2 s-1]
real, intent(in) :: dt !< Time-step [s]
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: scalar !< Scalar (scalar units [conc])
real, optional, intent(in) :: scale_factor !< Scale factor to get surfFlux
!! into proper units

integer :: i, j, k
real, dimension( SZI_(G), SZJ_(G),SZK_(GV) ) :: dtracer
real :: scale_factor_loc

if (present(scale_factor)) then
scale_factor_loc = scale_factor
else
scale_factor_loc = 1.0
endif

dtracer(:,:,:) = 0.0
!$OMP parallel do default(none) shared(dtracer, nonLocalTrans, h, G, GV, surfFlux, scale_factor_loc)
do k = 1, GV%ke
do j = G%jsc, G%jec
do i = G%isc, G%iec
dtracer(i,j,k) = ( nonLocalTrans(i,j,k) - nonLocalTrans(i,j,k+1) ) / &
( h(i,j,k) + GV%H_subroundoff ) * surfFlux(i,j) * scale_factor_loc
enddo
enddo
enddo

! Update tracer due to non-local redistribution of surface flux
if (applyNonLocalTrans) then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it desirable to call KPP_NonLocalTransport_passive_tracers when applyNonLocalTrans = False?
If yes, perhaps dtracer should only be calculated if applyNonLocalTrans = True or its diagnostic has been requested. If not, it would make more sense if this condition was outside of KPP_NonLocalTransport_passive_tracers.
The same comment applies for KPP_NonLocalTransport_temp and KPP_NonLocalTransport_saln.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The real issue is that I haven't plumbed in any diagnostics yet - for KPP_NonLocalTransport_temp and KPP_NonLocalTransport_saln, if applyNonLocalTrans is false then you still compute the terms and post the data, you just don't add the terms to the tracer quantities themselves... but when I first started working on this branch I got a little stuck trying to figure out how to include diagnostics and then I didn't come back to that before opening this PR

!$OMP parallel do default(none) shared(G, GV, dt, scalar, dtracer)
do k = 1, GV%ke
do j = G%jsc, G%jec
do i = G%isc, G%iec
scalar(i,j,k) = scalar(i,j,k) + dt * dtracer(i,j,k)
enddo
enddo
enddo
endif

end subroutine KPP_NonLocalTransport_passive_tracers


!> Clear pointers, deallocate memory
subroutine KPP_end(CS)
type(KPP_CS), pointer :: CS !< Control structure
Expand Down
6 changes: 5 additions & 1 deletion src/parameterizations/vertical/MOM_diabatic_driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ module MOM_diabatic_driver
use MOM_sponge, only : apply_sponge, sponge_CS
use MOM_ALE_sponge, only : apply_ALE_sponge, ALE_sponge_CS
use MOM_time_manager, only : time_type, real_to_time, operator(-), operator(<=)
use MOM_tracer_flow_control, only : call_tracer_column_fns, tracer_flow_control_CS
use MOM_tracer_flow_control, only : call_tracer_column_fns, call_tracer_KPP_NonLocalTransport, tracer_flow_control_CS
use MOM_tracer_diabatic, only : tracer_vertdiff, tracer_vertdiff_Eulerian
use MOM_unit_scaling, only : unit_scale_type
use MOM_variables, only : thermo_var_ptrs, vertvisc_type, accel_diag_ptrs
Expand Down Expand Up @@ -1504,6 +1504,10 @@ subroutine diabatic_ALE(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end,
G, GV, US, tv, CS%optics, CS%tracer_flow_CSp, CS%debug, &
evap_CFL_limit=CS%evap_CFL_limit, &
minimum_forcing_depth=CS%minimum_forcing_depth)
if (CS%useKPP) then
! Still need to apply nonlocal terms to passive tracers
call call_tracer_KPP_NonLocalTransport(G, GV, US, h, fluxes, CS%KPP_NLTscalar, US%T_to_s*dt, CS%tracer_flow_CSp)
endif

call cpu_clock_end(id_clock_tracers)

Expand Down
37 changes: 37 additions & 0 deletions src/tracer/MOM_CFC_cap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module MOM_CFC_cap
use MOM_forcing_type, only : forcing
use MOM_hor_index, only : hor_index_type
use MOM_grid, only : ocean_grid_type
use MOM_CVMix_KPP, only : KPP_NonLocalTransport_passive_tracers
use MOM_io, only : file_exists, MOM_read_data, slasher
use MOM_io, only : vardesc, var_desc, query_vardesc, stdout
use MOM_open_boundary, only : ocean_OBC_type
Expand All @@ -29,6 +30,7 @@ module MOM_CFC_cap

public register_CFC_cap, initialize_CFC_cap, CFC_cap_unit_tests
public CFC_cap_column_physics, CFC_cap_surface_state, CFC_cap_fluxes
public CFC_cap_KPP_NonLocalTransport
public CFC_cap_stock, CFC_cap_end

integer, parameter :: NTR = 2 !< the number of tracers in this module.
Expand All @@ -38,6 +40,7 @@ module MOM_CFC_cap
character(len=200) :: IC_file !< The file in which the CFC initial values can
!! be found, or an empty string for internal initilaization.
logical :: Z_IC_file !< If true, the IC_file is in Z-space. The default is false.
logical :: applyNonLocalTrans !< If true, apply nonlocal terms when using KPP for vertical mixing.
type(time_type), pointer :: Time => NULL() !< A pointer to the ocean model's clock.
type(tracer_registry_type), pointer :: tr_Reg => NULL() !< A pointer to the MOM6 tracer registry
real, pointer, dimension(:,:,:) :: &
Expand Down Expand Up @@ -112,6 +115,10 @@ function register_CFC_cap(HI, GV, param_file, CS, tr_Reg, restart_CS)
call get_param(param_file, mdl, "CFC_IC_FILE_IS_Z", CS%Z_IC_file, &
"If true, CFC_IC_FILE is in depth space, not layer space", &
default=.false.)
call get_param(param_file, mdl, "CFC_APPLY_NONLOCAL_TRANSPORT", CS%applyNonLocalTrans, &
"If true, the IC_file is in Z-space. The default is false.", &
"If True, applies the non-local transport to CFC tracers", &
default=.false.)
call get_param(param_file, mdl, "TRACERS_MAY_REINIT", CS%tracers_may_reinit, &
"If true, tracers may go through the initialization code "//&
"if they are not found in the restart files. Otherwise "//&
Expand Down Expand Up @@ -347,6 +354,36 @@ subroutine CFC_cap_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, US, C

end subroutine CFC_cap_column_physics


!>
subroutine CFC_cap_KPP_NonLocalTransport(G, GV, US, h, fluxes, nonLocalTrans, dt, CS)

type(ocean_grid_type), intent(in) :: G !< Ocean grid
type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer/level thickness [H ~> m or kg m-2]
type(forcing), intent(in) :: fluxes !< A structure containing pointers to
!! thermodynamic
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: nonLocalTrans !< Non-local transport [nondim]
real, intent(in) :: dt !< Time-step [s]
type(CFC_cap_CS), pointer :: CS !< A pointer that is set to point to the control

real :: scale_factor

scale_factor = 1.0 / (GV%rho0 * US%R_to_kg_m3)

call KPP_NonLocalTransport_passive_tracers(CS%applyNonLocalTrans, G, GV, h, nonLocalTrans, &
fluxes%cfc11_flux(:,:), dt, CS%CFC11(:,:,:), &
scale_factor = scale_factor)
call KPP_NonLocalTransport_passive_tracers(CS%applyNonLocalTrans, G, GV, h, nonLocalTrans, &
fluxes%cfc12_flux(:,:), dt, CS%CFC12(:,:,:), &
scale_factor = scale_factor)

! TODO: add diagnostics!

end subroutine CFC_cap_KPP_NonLocalTransport


!> 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.
Expand Down
24 changes: 23 additions & 1 deletion src/tracer/MOM_tracer_flow_control.F90
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module MOM_tracer_flow_control
use MOM_OCMIP2_CFC, only : OCMIP2_CFC_stock, OCMIP2_CFC_end, OCMIP2_CFC_CS
use MOM_CFC_cap, only : register_CFC_cap, initialize_CFC_cap
use MOM_CFC_cap, only : CFC_cap_column_physics, CFC_cap_surface_state
use MOM_CFC_cap, only : CFC_cap_KPP_NonLocalTransport
use MOM_CFC_cap, only : CFC_cap_stock, CFC_cap_end, CFC_cap_CS
use oil_tracer, only : register_oil_tracer, initialize_oil_tracer
use oil_tracer, only : oil_tracer_column_physics, oil_tracer_surface_state
Expand Down Expand Up @@ -71,7 +72,7 @@ module MOM_tracer_flow_control
implicit none ; private

public call_tracer_register, tracer_flow_control_init, call_tracer_set_forcing
public call_tracer_column_fns, call_tracer_surface_state, call_tracer_stocks
public call_tracer_column_fns, call_tracer_surface_state, call_tracer_stocks, call_tracer_KPP_NonLocalTransport
public call_tracer_flux_init, get_chl_from_model, tracer_flow_control_end

!> The control structure for orchestrating the calling of tracer packages
Expand Down Expand Up @@ -703,6 +704,27 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, CS, stock_names, stock_uni

end subroutine call_tracer_stocks


!> This routine calls all registered tracer KPP non-local transport subroutines.
subroutine call_tracer_KPP_NonLocalTransport(G, GV, US, h, fluxes, nonLocalTrans, dt, CS)

type(ocean_grid_type), intent(in) :: G !< Ocean grid
type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer/level thickness [H ~> m or kg m-2]
type(forcing), intent(in) :: fluxes !< A structure containing pointers to
!! any possible forcing fields.
!! Unused fields have NULL ptrs.
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: nonLocalTrans !< Non-local transport [nondim]
real, intent(in) :: dt !< Time-step [s]
type(tracer_flow_control_CS), pointer :: CS !< The control structure returned by
!! a previous call to call_tracer_register

if (CS%use_CFC_cap) &
call CFC_cap_KPP_NonLocalTransport(G, GV, US, h, fluxes, nonLocalTrans, dt, CS%CFC_cap_CSp)

end subroutine call_tracer_KPP_NonLocalTransport

!> This routine stores the stocks and does error handling for call_tracer_stocks.
subroutine store_stocks(pkg_name, ns, names, units, values, index, stock_values, &
set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
Expand Down