-
Notifications
You must be signed in to change notification settings - Fork 216
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
Conversation
ImmersedBoundaries
bottom_height
interface
Correction: |
Is 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this change?
There was a problem hiding this comment.
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] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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".
There was a problem hiding this comment.
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))!") |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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)
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? |
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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this used?
There was a problem hiding this comment.
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
Line 62 in 6c40d7e
d_up = Cˢ * depthᶜᶜᶠ(i, j, k, grid) |
There was a problem hiding this comment.
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
# 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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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⁺) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
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 |
static_column_depth
interfacestatic_column_depth
interface and numerical bottom height in AbstractGridFittedBottom
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. internal_tide.mp4 |
In the new commit, I reverted to the previous implementation, so now there is no difference internal_tide.mp4 |
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 forGridFittedBottom
, removing the necessity of having aCenterImmersedCondition
and aInterfaceImmersedCondition
.An immediate application of this interface is in the
SplitExplicitFreeSurface
where the bottom_height was previously stored.