Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Subgrid diffusive fluxes for from closure for tracers#255

Open
jeremy-lilly wants to merge 9 commits into
tomchor:mainfrom
jeremy-lilly:diffusive-flux
Open

Subgrid diffusive fluxes for from closure for tracers#255
jeremy-lilly wants to merge 9 commits into
tomchor:mainfrom
jeremy-lilly:diffusive-flux

Conversation

@jeremy-lilly

Copy link
Copy Markdown

This PR adds diagnostic functions for calculating subgrid fluxes for tracers that are determined by the configured closure.

The user exposed routines DiffusiveFluxX, DiffusiveFluxY, and DiffusiveFluxZ use the native Oceananigans kernels diffusive_flux_x, diffusive_flux_y, and diffusive_flux_z respectively.

@jeremy-lilly

Copy link
Copy Markdown
Author

Hey @tomchor -- Just a heads up that I will be on vacation and unresponsive for the next ~week, but I wanted to get out for review before I left. Thanks!

@tomchor

tomchor commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Hey @tomchor -- Just a heads up that I will be on vacation and unresponsive for the next ~week, but I wanted to get out for review before I left. Thanks!

That's alright, I'll also be out of office next week so that's pretty good timing lol

I'll try to review it tomorrow. Thanks for the PR!

Comment thread src/TracerEquation.jl Outdated
Comment thread src/TracerEquation.jl Outdated
Comment on lines +25 to +27
const DiffusiveFluxX = CustomKFO{<:typeof(diffusive_flux_x)}
const DiffusiveFluxY = CustomKFO{<:typeof(diffusive_flux_y)}
const DiffusiveFluxZ = CustomKFO{<:typeof(diffusive_flux_z)}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Can we name these to XDiffusiveFlux etc? It matches previous notation in the repo and it sounds more like how one would say these in plain english

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

My rational for this naming convention was to match the diffusive_flux_* kernels from Oceananigans. If you still want it changed, I don't mind.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I see your reasoning, but we made the decision a while ago to standard the user interfaces like this even though the underlying kernels might be different. For example:

function TurbulentKineticEnergyZShearProductionRate(u′, v′, w′, U, V, W;
grid = u′.grid,
location = (Center, Center, Center))
validate_location(location, "TurbulentKineticEnergyZShearProductionRate")
return KernelFunctionOperation{Center, Center, Center}(shear_production_rate_z_ccc, grid,
u′, v′, w′, U, V, W)
end

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Make sense to me! Done in dabec1a.

Comment thread test/test_tracer_diagnostics.jl Outdated
Comment on lines +103 to +104
DIFF_FLUX = TracerEquation.DiffusiveFluxX(model, model.grid, model.closure, model.closure_fields,
Val(:a), model.tracers.a, model.clock, fields(model), model.buoyancy)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Can we align these? I think the suggestion below does it but it's kinda hard to tell on github

Suggested change
DIFF_FLUX = TracerEquation.DiffusiveFluxX(model, model.grid, model.closure, model.closure_fields,
Val(:a), model.tracers.a, model.clock, fields(model), model.buoyancy)
DIFF_FLUX = TracerEquation.DiffusiveFluxX(model, model.grid, model.closure, model.closure_fields,
Val(:a), model.tracers.a, model.clock, fields(model), model.buoyancy)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Happy to fix this as well, but wanted to check if you wanted all similar lines in this file changed similarly? It looks like the existing function calls are also indented like this.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Yeah, usually we align all these lines to improve readability. I'm open to other ways of alignment as well, but I think before it wasn't aligned with anything

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in b579203.

@tomchor tomchor left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Nice! Made some very minor comments but I'm happy to merge after they're done. Thanks for the contribution!

...And also after tests pass... :)

@jeremy-lilly

Copy link
Copy Markdown
Author

Nice! Made some very minor comments but I'm happy to merge after they're done. Thanks for the contribution!

...And also after tests pass... :)

No problem at all! Happy to contribute!

As for tests passing, just copying this here for myself:

[ Info:         Testing tracer terms
Tracer variance diagnostics tests: Error During Test at /home/runner/work/Oceanostics.jl/Oceanostics.jl/test/test_tracer_diagnostics.jl:158
  Got exception outside of a @test
  MethodError: no method matching diffusive_flux_x(::Int64, ::Int64, ::Int64, ::ImmersedBoundaryGrid{Float64, Periodic, Periodic, Bounded, RectilinearGrid{Float64, Periodic, Periodic, Bounded, Oceananigans.Grids.StaticVerticalDiscretization{OffsetArrays.OffsetVector{Float64, Vector{Float64}}, 

Probably a typo somewhere -- I will update you when I track it down : )

@tomchor

tomchor commented Jul 4, 2026

Copy link
Copy Markdown
Owner

@jeremy-lilly if it's easier I can also add you to the repo. That way you can run the tests yourself online and don't have to be running them locally (I assumed that's what the last post was about?)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends Oceanostics.TracerEquation with new diagnostic kernel-function operations for computing closure-determined subgrid diffusive tracer fluxes (diffusive_flux_x/y/z), and adds corresponding unit tests.

Changes:

  • Add DiffusiveFluxX, DiffusiveFluxY, and DiffusiveFluxZ diagnostics backed by Oceananigans’ diffusive_flux_x/y/z kernels.
  • Introduce tracer-specific aliases TracerDiffusiveFluxX/Y/Z.
  • Extend tracer diagnostics tests to cover the new diffusive flux diagnostics and their Field wrapping.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 11 comments.

File Description
src/TracerEquation.jl Adds diffusive-flux diagnostic constructors, type aliases, and docstrings for tracer subgrid fluxes.
test/test_tracer_diagnostics.jl Adds tests asserting the new diffusive-flux diagnostics construct correctly and can be wrapped as Fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/TracerEquation.jl Outdated
Comment thread test/test_tracer_diagnostics.jl Outdated
Comment on lines +104 to +108
Val(:a), model.tracers.a, model.clock, fields(model), model.buoyancy)
DIFF_FLUX_field = Field(DIFF_FLUX)
@test DIFF_FLUX isa TracerEquation.DiffusiveFluxX
@test DIFF_FLUX isa TracerDiffusiveFluxX
@test DIFF_FLUX_field isa Field

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The convention in Oceanostics is that diagnostics can be available in the namespace as

Oceanostics.TracerEquation.TracerDiffusiveFluxX
Oceanostics.TracerEquation.DiffusiveFluxX

or

Oceanostics.TracerDiffusiveFluxX

for all diagnostics.

But you can't do

Oceanostics.DiffusiveFluxX

because then it's ambiguous what is being fluxed.

So I suggest reviewing the exports to make sure they're in line.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in 3d63544.

Comment thread test/test_tracer_diagnostics.jl Outdated
Comment thread test/test_tracer_diagnostics.jl Outdated
Comment thread test/test_tracer_diagnostics.jl Outdated
Comment thread test/test_tracer_diagnostics.jl Outdated
Comment thread src/TracerEquation.jl Outdated
Comment on lines +220 to +224
function DiffusiveFluxX(model, tracer_name; kwargs...)
tracer_index = findfirst(x -> x == tracer_name, keys(model.tracers))
tracer = model.tracers[tracer_index]
return DiffusiveFluxX(model, model.grid, model.closure, model.closure_fields, Val(tracer_index), tracer, model.clock, fields(model), model.buoyancy; kwargs...)
end

@tomchor tomchor Jul 5, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I agree with this comment! (And same for the other directions)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in 67ccb49.

Comment thread src/TracerEquation.jl Outdated
Comment thread src/TracerEquation.jl Outdated
Comment thread src/TracerEquation.jl Outdated
Comment on lines +215 to +218
function DiffusiveFluxX(model, grid, closure, closure_fields, val_tracer_index, tracer, clock, model_fields, buoyancy; location = (Face, Center, Center))
validate_location(location, "DiffusiveFluxX", (Face, Center, Center))
return KernelFunctionOperation{Face, Center, Center}(diffusive_flux_x, grid, closure, closure_fields, val_tracer_index, tracer, clock, model_fields, buoyancy)
end

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I think I agree with this too. Can you please double check @jeremy-lilly ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed, this is a good change to make -- see be529b9.

@tomchor, the other routines in TracerEquation.jl have a similar issue where there are redundant fields required -- I'm happy to clean those up as well if you want.

@tomchor

tomchor commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Asked copilot to give a review but I guess it went a little crazy lol
I can go over each comment next week to weed out the non-relevant comments

@tomchor

tomchor commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Resolved the comments by copilot that were repetitive and that I didn't agree with. The remainder comments are the relevant ones

@jeremy-lilly

Copy link
Copy Markdown
Author

Resolved the comments by copilot that were repetitive and that I didn't agree with. The remainder comments are the relevant ones

Thank you @tomchor! I will look through these comments and resolve them as I have time -- I will ping you when ready for another look : )

@jeremy-lilly

Copy link
Copy Markdown
Author

Nice! Made some very minor comments but I'm happy to merge after they're done. Thanks for the contribution!
...And also after tests pass... :)

No problem at all! Happy to contribute!

As for tests passing, just copying this here for myself:

[ Info:         Testing tracer terms
Tracer variance diagnostics tests: Error During Test at /home/runner/work/Oceanostics.jl/Oceanostics.jl/test/test_tracer_diagnostics.jl:158
  Got exception outside of a @test
  MethodError: no method matching diffusive_flux_x(::Int64, ::Int64, ::Int64, ::ImmersedBoundaryGrid{Float64, Periodic, Periodic, Bounded, RectilinearGrid{Float64, Periodic, Periodic, Bounded, Oceananigans.Grids.StaticVerticalDiscretization{OffsetArrays.OffsetVector{Float64, Vector{Float64}}, 

Probably a typo somewhere -- I will update you when I track it down : )

This should be fixed by 24fb64c. The diffusive_flux_x,y,z kernels require that model.closure != nothing, so we are now testing these on a separate instance of model, where model.closure == ScalarDiffusivity().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants