Skip to content

Allow arbitrary fluxes across immersed boundaries and test this with AdvectiveForcing#4987

Merged
glwagner merged 32 commits intomainfrom
tc/unify-adv-forcing-bc
Dec 8, 2025
Merged

Allow arbitrary fluxes across immersed boundaries and test this with AdvectiveForcing#4987
glwagner merged 32 commits intomainfrom
tc/unify-adv-forcing-bc

Conversation

@tomchor
Copy link
Copy Markdown
Member

@tomchor tomchor commented Nov 25, 2025

This PR makes it possible for users to enforce both open and closed boundaries for AdvectiveForcing for both immersed and domain boundaries. This is done by removing methods that enforced zero-flux through immersed boundaries. I'm also adding a test for this and a validation script which produces the following animations for open and closed boundaries, respectively:

nonhydrostatic_tracer_circle_2d_compare_open.mp4
nonhydrostatic_tracer_circle_2d_compare.mp4

I also fixed a few errors/typos in other validation scripts.

Importantly, even after this PR, if a user passes a Number to AdvectiveForcing the behavior at domain and immersed boundaries remains different. Therefore this does not close #4812, since a Field with proper boundary conditions is required to unify behavior across different boundaries.

@tomchor
Copy link
Copy Markdown
Member Author

tomchor commented Dec 3, 2025

Re-centering and updating the discussion around face boundary conditions for AdvectiveForcing here. Per #4998 (comment), @glwagner suggested that the BCs for AdvectiveForcing be imposed by masking the immersed values to the appropriate value.

This by itself doesn't seem to work. For example, in the example below, AdvectiveForcing.w is equal to -0.02 everywhere, including in the immersed solid and domain faces. I'd expect both cases to result in the tracer passing through the boundaries, but instead the tracer accumulates in the immersed boundary:

nonhydrostatic_tracer_circle_2d_compare.mp4

@glwagner did I miss something about your suggestion?

@glwagner
Copy link
Copy Markdown
Member

glwagner commented Dec 3, 2025

Re-centering and updating the discussion around face boundary conditions for AdvectiveForcing here. Per #4998 (comment), @glwagner suggested that the BCs for AdvectiveForcing be imposed by masking the immersed values to the appropriate value.

This by itself doesn't seem to work. For example, in the example below, AdvectiveForcing.w is equal to -0.02 everywhere, including in the immersed solid and domain faces. I'd expect both cases to result in the tracer passing through the boundaries, but instead the tracer accumulates in the immersed boundary:

nonhydrostatic_tracer_circle_2d_compare.mp4
@glwagner did I miss something about your suggestion?

You didn't miss anything. This reveals that there is more work to do. Try commenting out these specializations for immersed boundary grid:

@inline _advective_tracer_flux_x(i, j, k, ibg::IBG, scheme, U, c) = conditional_flux_fcc(i, j, k, ibg, zero(ibg), advective_tracer_flux_x(i, j, k, ibg, scheme, U, c))
@inline _advective_tracer_flux_y(i, j, k, ibg::IBG, scheme, V, c) = conditional_flux_cfc(i, j, k, ibg, zero(ibg), advective_tracer_flux_y(i, j, k, ibg, scheme, V, c))
@inline _advective_tracer_flux_z(i, j, k, ibg::IBG, scheme, W, c) = conditional_flux_ccf(i, j, k, ibg, zero(ibg), advective_tracer_flux_z(i, j, k, ibg, scheme, W, c))

these seem to hardcode impenetrability for an immersed boundary grid.

@simone-silvestri may want to comment on this. I think we have discussed about how the conditional advection operators are redundant with masking. If users want to have open immersed boundaries, we will need to stop using conditional advection operators that assume impenetrability on immersed boundaries.

@simone-silvestri
Copy link
Copy Markdown
Collaborator

I guess we could just remove these. The flux on the immersed boundaries will be zeroed by masking the velocities.

@tomchor
Copy link
Copy Markdown
Member Author

tomchor commented Dec 3, 2025

This does seem to work. Let's see if removing this doesn't break any tests.

@simone-silvestri
Copy link
Copy Markdown
Collaborator

simone-silvestri commented Dec 4, 2025

I think the momentum fluxes might require a bit more work, since momentum fluxes always require interpolation of both advecting and advected velocities, and we do not have three-dimensional interpolation operators yet, so the velocity interpolated at the face might not be zero, leading to a non-zero flux across the immersed boundary.

@tomchor tomchor marked this pull request as ready for review December 4, 2025 14:13
@tomchor tomchor requested a review from glwagner December 4, 2025 14:19
@tomchor
Copy link
Copy Markdown
Member Author

tomchor commented Dec 5, 2025

@glwagner @simone-silvestri if tests pass this should be ready (they passed locally for me).

@tomchor tomchor changed the title Unify boundary behavior of AdvectiveForcing between immersed boundary and domain boundary Allow arbitrary fluxes across immersed boundaries and test this with AdvectiveForcing Dec 5, 2025
@tomchor tomchor requested a review from glwagner December 7, 2025 22:28
Copy link
Copy Markdown
Member

@glwagner glwagner left a comment

Choose a reason for hiding this comment

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

nice work @tomchor !

@glwagner glwagner merged commit 7027ff4 into main Dec 8, 2025
119 of 123 checks passed
@glwagner glwagner deleted the tc/unify-adv-forcing-bc branch December 8, 2025 16:02
@simone-silvestri
Copy link
Copy Markdown
Collaborator

I was looking at this PR again and I still think removing the momentum flux zeroing on immersed boundaries might still be wrong because of the fact that we do not have boundary-aware interpolation. Is this tested? How was it solved?

@tomchor
Copy link
Copy Markdown
Member Author

tomchor commented Mar 10, 2026

I was looking at this PR again and I still think removing the momentum flux zeroing on immersed boundaries might still be wrong because of the fact that we do not have boundary-aware interpolation. Is this tested? How was it solved?

Is was tested with the added validation script and the added test, but that's about it.

@simone-silvestri
Copy link
Copy Markdown
Collaborator

Would it be possible to add a test for all the advection schemes that should that independently of the internal solution, when computing the momentum flux on peripheral nodes it is zero?

tomchor added a commit that referenced this pull request Mar 16, 2026
Tests that all 9 advective momentum flux kernels return zero at
immersed peripheral nodes, for Centered(2), UpwindBiased(3), and
WENO(5). This documents the expected behavior after PR #4987 removed
the explicit conditional_flux zeroing from _advective_momentum_flux_*
on ImmersedBoundaryGrid, relying instead on velocity masking in
immersed cells and the no-penetration BC at the boundary face.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@tomchor
Copy link
Copy Markdown
Member Author

tomchor commented Mar 16, 2026

@simone-silvestri added #5402

Can you double check if that's what you meant?

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.

Different behavior of AdvectiveForcing when tracers encounter a domain boundary and an immersed boundary

3 participants