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

static_column_depth interface and numerical bottom height in AbstractGridFittedBottom #3841

Merged
merged 107 commits into from
Nov 9, 2024

Conversation

simone-silvestri
Copy link
Collaborator

@simone-silvestri simone-silvestri commented Oct 9, 2024

This PR introduces an interface for static_column_depth that returns the height of the water column (not including the free surface).
This is simply grid.Lz in regular grids.

For AbstractGridFittedBottom immersed grids, the column height is readily read from the immersed boundary, provided that the immersed boundary represents the numerical bottom rather than the physical bottom.

Therefore, this PR changes the constructor of the ImmersedBoundaryGrid to store the z-coordinate of the last immersed cell. In this way, the bottom height is also uniquely defined for GridFittedBottom, removing the necessity of having aCenterImmersedCondition and a InterfaceImmersedCondition.

An immediate application of this interface is in the SplitExplicitFreeSurface where the bottom_height was previously stored.

@simone-silvestri simone-silvestri changed the title Bottom height for ImmersedBoundaries bottom_height interface Oct 9, 2024
@simone-silvestri simone-silvestri changed the title bottom_height interface column_height interface Oct 9, 2024
@simone-silvestri
Copy link
Collaborator Author

Correction: InterfaceImmersedCondition and CenterImmersedCondition might still useful during construction because they inform where the bottom height will be.

@glwagner
Copy link
Member

glwagner commented Oct 9, 2024

Is column_height a good name?

There's a naming issue. We had previously referred to "z" as "height". Usually this doesn't matter but when it does, eg in realistic contexts and using nonlinear equation of state, then we are trying to be consistent with the literature where "z" is the "geopotential height".

We can change the user-facing naming and notation for sure but it has to be done carefully and with consensus. I think this PR makes some big changes to notation and language that could have wide-ranging impacts on how we communicate about numerical models.


struct GridFittedBottom{H, I} <: AbstractGridFittedBottom{H}
bottom_height :: H
z_bottom :: H
Copy link
Member

Choose a reason for hiding this comment

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

why this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I though we want to refer to z as the coordinate and height as a positive value.
At least, this is the direction we are taking in ClimaOcean where we are distinguishing very carefully between z and h or height.
In this case, this is technically a coordinate, not a height, for example we have now

@inline z_bottom(i, j, ibg::GFBIBG) = @inbounds ibg.immersed_boundary.bottom_height[i, j, 1]
which conflates the meaning of z with height. I thought we had decided this over at ClimaOcean and I wanted to update this code to reflect the decision we had made.

Copy link
Member

@glwagner glwagner Oct 9, 2024

Choose a reason for hiding this comment

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

I though we want to refer to z as the coordinate and height as a positive value.

Usually "z" is called "geopotential height". In the way it's usually used, height can be positive or negative; the point is that it increases as we go upwards away from the center of the Earth (as opposed to "depth" which increases downwards). What would you call "z" instead? Altitude?

Copy link
Member

Choose a reason for hiding this comment

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

this is technically a coordinate, not a height

Another name for z is "height coordinate".

Copy link
Collaborator

Choose a reason for hiding this comment

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

As someone who hasn't used immersed boundaries that much, I always find it a bit confusing that it's called bottom height because it makes me think I'm meant to put in a positive "height" from the bottom of the domain, but I would know that "z" is meant to be from the top

@@ -92,10 +95,6 @@ with_halo(halo, ibg::ImmersedBoundaryGrid) =
inflate_halo_size_one_dimension(req_H, old_H, _, ::IBG) = max(req_H + 1, old_H)
inflate_halo_size_one_dimension(req_H, old_H, ::Type{Flat}, ::IBG) = 0

# Defining the bottom
@inline z_bottom(i, j, grid) = znode(i, j, 1, grid, c, c, f)
@inline z_bottom(i, j, ibg::IBG) = error("The function `bottom` has not been defined for $(summary(ibg))!")
Copy link
Member

Choose a reason for hiding this comment

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

isn't this still useful? Why delete it?

Copy link
Collaborator Author

@simone-silvestri simone-silvestri Nov 7, 2024

Choose a reason for hiding this comment

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

I have moved it in the TurbulenceClosures module where also z_top and height_above_bottom are defined. I think it's cleaner to have all these functions in the same place. If I have to guess why they were not is because the ImmersedBoundaries module was defined after the TurbulenceClosures module. Since this is not the case anymore, this is a bit of a cleanup.

Copy link
Member

Choose a reason for hiding this comment

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

Ok so its unrelated to the static column depth? I feel z_bottom belongs in the Grids module. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Consider that it has to be extended for different immersed boundary implementation so it depends on partial cell bottom, etc.

The original implementation may not have been optimal, but since we are moving things around here, I think we should try to improve on the original organization.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am ok with moving all these functions in the Grids module, shall we do it in this PR?


Adapt.adapt_structure(to, ib::GridFittedBottom) = GridFittedBottom(adapt(to, ib.bottom_height),
ib.immersed_condition)
@inline static_column_depthᶠᶜᵃ(i, j, ibg::XFlatAGFIBG) = static_column_depthᶜᶜᵃ(i, j, ibg)
Copy link
Member

Choose a reason for hiding this comment

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

when this happens it could suggest that this should be more like node with

static_column_depth(i, j, grid, lx, ly)

@glwagner
Copy link
Member

glwagner commented Nov 6, 2024

I'm confused about this PR. There are all sorts of changes in different places. There is even a change to the Makie extension. What am I reviewing?

@simone-silvestri
Copy link
Collaborator Author

I have merged in #3880 because I wanted to see if the GPU tests pass. I am planning to merge this PR after that one. The rest is all from this PR. The OceananigansMakieExt change is a typo fix, but I see you have added a PR for it.

@inline depthᶜᶜᶜ(i, j, k, grid) = clip(z_top(i, j, grid) - znode(i, j, k, grid, c, c, c))
@inline total_depthᶜᶜᵃ(i, j, grid) = clip(z_top(i, j, grid) - z_bottom(i, j, grid))
@inline depthᶜᶜᶠ(i, j, k, grid) = clip(z_top(i, j, grid) - znode(i, j, k, grid, c, c, f))
@inline depthᶜᶜᶜ(i, j, k, grid) = clip(z_top(i, j, grid) - znode(i, j, k, grid, c, c, c))
Copy link
Member

Choose a reason for hiding this comment

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

is this used?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

seems to be used in CATKE here for example

Copy link
Member

Choose a reason for hiding this comment

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

ah yes, this is local depth vs the column depth

Comment on lines 91 to 93
# If the size of the bottom cell is less than ϵ Δz, use
# a simple `GridFittedBottom` approach where the bottom
# height is the top interface of cell k.
Copy link
Member

Choose a reason for hiding this comment

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

This is a different numerical method than what we implemented, isn't it? Previously we would "open up" small cells. This seems to "close" them.

Copy link
Member

Choose a reason for hiding this comment

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

Which is a fine proposal but I think you should change the title of the PR. Imagine us looking for what is causing this kind of different in the future, combing through PRs. It's pretty hidden in this one

Copy link
Member

Choose a reason for hiding this comment

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

Could end up being the most important change in this PR

Copy link
Collaborator Author

@simone-silvestri simone-silvestri Nov 7, 2024

Choose a reason for hiding this comment

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

Hmmm, I thought there was supposed to be no difference.
Here, the bottom_height is set to the actual bottom height if it is smaller than z⁻ + ϵ Δz; otherwise, the cell is closed.
So, the only difference with the main branch will be for bottom heights that are in between z⁻ + ϵ Δz and z⁺ (where z⁻ and z⁺ are the interfaces of the bottom cell).
I will check the difference in the internal_tide example.

Copy link
Member

Choose a reason for hiding this comment

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

But I thought before we would keep the cell open (rather than closing it).

Actually I think that MITgcm uses some criteria to decide which one to do --- either snapping up or down depending on which change is least.

Copy link
Collaborator Author

@simone-silvestri simone-silvestri Nov 7, 2024

Choose a reason for hiding this comment

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

Ah, ok, I understand; open till ϵ Δz instead of snapping up. Yeah, this is definitely different.

Copy link
Member

Choose a reason for hiding this comment

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

Actually I think we used to use that criteria too. It's something like

partial_Δz = z⁺ - zb
too_thin = partial_Δz < ϵ * Δz
snap_up = partial_Δz < ϵ * Δz / 2
snapped_zb = ifelse(snap_up, z⁺, z⁻ + ϵ * Δz)
numerical_zb  = ifelse(too_thin, snapped_zb, zb)

# If the size of the bottom cell is less than ϵ Δz, use
# a simple `GridFittedBottom` approach where the bottom
# height is the top interface of cell k.
capped_zb = ifelse(zb < z⁻ + Δz * (1 - ϵ), zb, z⁺)
Copy link
Member

@glwagner glwagner Nov 7, 2024

Choose a reason for hiding this comment

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

Suggested change
capped_zb = ifelse(zb < z⁻ + Δz * (1 - ϵ), zb, z⁺)
partial_Δz = z⁺ - zb
too_thin = partial_Δz < ϵ * Δz
adjusted_zb = ifelse(too_thin, z⁺, zb) # adjust bottom height to eliminate thin cells

Copy link
Member

Choose a reason for hiding this comment

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

this just makes it easier to understand. I was having trouble with the math. Also I think it's convoluted to evaluate the criterion by using the interface below and then adding Δz to both sides, isn't it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

right, I have modified it

@glwagner
Copy link
Member

glwagner commented Nov 7, 2024

can you run and show is the results from the internal tide example just to be sure, because this PR changes the partial cell algorithm

@simone-silvestri simone-silvestri changed the title static_column_depth interface static_column_depth interface and numerical bottom height in AbstractGridFittedBottom Nov 7, 2024
@simone-silvestri
Copy link
Collaborator Author

This is the difference in the internal tide example. I hadn't appreciated this difference. Maybe I can revert the implementation so that this PR does not really change the behavior, and we can look more in-depth at what MITgcm does in another PR.
I also think we need some tests for the Partial cells, so that would be a good excuse to also look at the formulation.

internal_tide.mp4

@simone-silvestri
Copy link
Collaborator Author

In the new commit, I reverted to the previous implementation, so now there is no difference

internal_tide.mp4

@simone-silvestri simone-silvestri merged commit ec4ac22 into main Nov 9, 2024
46 checks passed
@simone-silvestri simone-silvestri deleted the ss/new-bottom-height branch November 9, 2024 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants