Repository navigation
Add specialized limiter function for AMR coarsen and refine - #164
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #164 +/- ##
==========================================
+ Coverage 97.47% 99.07% +1.60%
==========================================
Files 105 104 -1
Lines 5565 5576 +11
==========================================
+ Hits 5424 5524 +100
+ Misses 141 52 -89 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Just to get it right: merging trixi-framework/Trixi.jl#2396 broke something in TrixiShallowWater.jl, since it used non-public API, correct? Can you add one of the elixirs affected by this to the downstream tests of TrixiShallowWater.jl that Trixi.jl executes for new PRs, please? |
ranocha
left a comment
There was a problem hiding this comment.
Thanks! This might be worth a NEWS.md entry. I will review the changes in more details.
ranocha
left a comment
There was a problem hiding this comment.
Thanks, this looks good overall. You also need to require a newer version of Trixi.jl (in Project.toml) including the feature to use limiters for AMR.
| # We compute the value directly with the mean values, as we assume that | ||
| # Jensen's inequality holds (e.g. pressure for compressible Euler equations). | ||
| value_mean = variable(u_mean, equations) | ||
| theta = (value_mean - threshold) / (value_mean - value_min) |
There was a problem hiding this comment.
TrixiShallowWater.jl limits only the water height, correct? Thus, it would be better to write something like
| # We compute the value directly with the mean values, as we assume that | |
| # Jensen's inequality holds (e.g. pressure for compressible Euler equations). | |
| value_mean = variable(u_mean, equations) | |
| theta = (value_mean - threshold) / (value_mean - value_min) | |
| # We compute the value directly with the mean values. In the general | |
| # case, this requires Jensen's inequality, e.g., for the pressure for | |
| # the compressible Euler equations. However, we only need linear | |
| # variables such as the `waterheight` here, where this is satisfied. | |
| value_mean = variable(u_mean, equations) | |
| theta = (value_mean - threshold) / (value_mean - value_min) |
| u_node = get_node_vars(u, equations, dg, i, j, new_element_id) | ||
|
|
||
| # Cut off velocity in case that the water height is smaller than the threshold | ||
|
|
||
| h_node, h_v1_node, h_v2_node, b_node = u_node | ||
| h_mean, h_v1_mean, h_v2_mean, _ = u_mean # b_mean is not used as it must not be overwritten | ||
|
|
||
| if h_node <= threshold | ||
| h_v1_node = zero(eltype(u)) | ||
| h_v2_node = zero(eltype(u)) | ||
| h_v1_mean = zero(eltype(u)) | ||
| h_v2_mean = zero(eltype(u)) | ||
| end | ||
|
|
||
| u_node = SVector(h_node, h_v1_node, h_v2_node, b_node) | ||
| u_mean = SVector(h_mean, h_v1_mean, h_v2_mean, b_node) | ||
|
|
||
| # When velocities are cut off, the only averaged value is the water height, | ||
| # because the velocities are set to zero and this value is passed. | ||
| # Otherwise, the velocities are averaged, as well. | ||
| # Note that the auxiliary bottom topography variable `b` is never limited. | ||
| set_node_vars!(u, theta * u_node + (1 - theta) * u_mean, | ||
| equations, dg, i, j, new_element_id) |
There was a problem hiding this comment.
It looks like there is some duplication of code around inner blocks like this one. Did you check whether it could make sense to put parts like this one into the own (@inlined) functions?
There was a problem hiding this comment.
That's a good point. I can double check if there are places where introducing a helper function is warranted.
There was a problem hiding this comment.
If you @inline them, there will be no performance penalty.
| # Version used by the AMR callback | ||
| function (limiter!::PositivityPreservingLimiterShallowWater)(u, mesh, equations, solver, | ||
| cache, args...) | ||
| limiter_shallow_water!(u, limiter!.variables, mesh, equations, | ||
| solver, cache, args...) | ||
| end |
There was a problem hiding this comment.
Something else that just came to my mind: What about the 1D case? As far as I see, only the 2D case is changed. However, this allow the 1D case as well.
There was a problem hiding this comment.
Currently, the AMR in TrixiShallowWater is only available in 2D and only on P4estMesh. This is because we need special projections to and from the mortars to make sure that the simulation stays well-balanced. I never bothered to implement these projections on TreeMesh. That is why I did not modify the 1D variant of the limiters.
There was a problem hiding this comment.
You don't need projections in 1D since there are no mortars, are there?
There was a problem hiding this comment.
Ah, a fantastic point! In 1D there are no mortars so it would be possible to do AMR with some modified limiters. I can try out such a run and add it to this PR or do a separate 1D PR, depending on how much additional code needs touched.
There was a problem hiding this comment.
Doing it in another PR would be perfectly fine. It would just be good to have this on the agenda, since some parts of the new code here allow 1D while others are specialized for 2D.
There was a problem hiding this comment.
I will do the 1D version in a different PR.
| if h_node <= threshold | ||
| h_v1_node = zero(eltype(u)) | ||
| h_v2_node = zero(eltype(u)) | ||
| h_v1_mean = zero(eltype(u)) | ||
| h_v2_mean = zero(eltype(u)) | ||
| end | ||
|
|
||
| u_node = SVector(h_node, h_v1_node, h_v2_node, b_node) | ||
| u_mean = SVector(h_mean, h_v1_mean, h_v2_mean, b_node) |
There was a problem hiding this comment.
This makes me feel a bit unhappy. If I understand it correctly, the mean value u_mean is computed first and then used to update the values in the child cells. However, the mean value of the momentum is set to zero if the nodal value at some point has h_node <= threshold. Thus, a zero momentum will propagate to other nodes, even with h_node > threshold, if they ocme after a dry node. This is likely not what we want, is it?
A solution could be to avoid overwriting u_mean by instead using something like
| if h_node <= threshold | |
| h_v1_node = zero(eltype(u)) | |
| h_v2_node = zero(eltype(u)) | |
| h_v1_mean = zero(eltype(u)) | |
| h_v2_mean = zero(eltype(u)) | |
| end | |
| u_node = SVector(h_node, h_v1_node, h_v2_node, b_node) | |
| u_mean = SVector(h_mean, h_v1_mean, h_v2_mean, b_node) | |
| if h_node <= threshold | |
| h_v1_node = zero(eltype(u)) | |
| h_v2_node = zero(eltype(u)) | |
| h_v1_mean = zero(eltype(u)) | |
| h_v2_mean = zero(eltype(u)) | |
| end | |
| u_node = SVector(h_node, h_v1_node, h_v2_node, b_node) | |
| u_mean_local = SVector(h_mean, h_v1_mean, h_v2_mean, b_node) |
and using u_mean_local instead of u_mean below.
This situation should then be explained in a comment around this assignment. The same kind of observation holds for other cases as well.
There was a problem hiding this comment.
Ah, yes. That is a possibility the zero momentum value could propagate beyond the node where we apply the cutoff. I can change and test this out.
There was a problem hiding this comment.
Using the u_mean_local to ensure that only the node i,j is affected ended up slightly changing some test values of other wet/dry test cases.
Yes, that is what happened. TrixiShallowWater was using a specialized version of coarsen / refine routines that had a "band-aid" hard coded limiter call. With the release of Trixi version 0.16.24 (that is used by the CI testing) the API change caused the TrixiShallowWater tests to then fallback to using the The limiting strategy from trixi-framework/Trixi.jl#2396 is the correct approach now that the AMR callback can accept the I will add one of the wet/dry + AMR elixirs to the downstream tests as this is a much tougher test than the fully wet AMR test that is currently in the downstream. |
|
I have run into an issue that I am unsure the best way to solve. I added one of the AMR + wet/dry tests to Should I add logic in |
Co-authored-by: Hendrik Ranocha <ranocha@users.noreply.github.com>
f3adf8a
into
trixi-framework:main
|
Thanks! |

This adds specialized instances of
PositivityPreservingLimiterShallowWaterfor use with the AMR coarsen and refine strategy now used in Trixi as #2396 there has been merged to main. This should fix the failingP4estMeshtests that have AMR and wet/dry.Moreover, this removes the "band-aid" specialized AMR routines that hard-coded a limiter call that were introduced in #97. As that functionality was marked as experimental, this shouldn't be a breaking change.