-
Notifications
You must be signed in to change notification settings - Fork 190
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
Implementation of the scale-dependent Lagrangian-averaged dynamic Smagorinsky #3638
base: main
Are you sure you want to change the base?
Conversation
@@ -225,6 +225,8 @@ end | |||
u̅w̅ = ℑxyzᶜᶜᶜ(i, j, k, grid, ℑxyzᶠᶠᶠ, ℑxyzᶜᶜᶜ, ℑxyzᶠᶠᶠ, uᵢuⱼ, ℑxᶜᵃᵃ, ℑzᵃᵃᶜ, u, w) | |||
v̅w̅ = ℑxyzᶜᶜᶜ(i, j, k, grid, ℑxyzᶠᶠᶠ, ℑxyzᶜᶜᶜ, ℑxyzᶠᶠᶠ, uᵢuⱼ, ℑyᵃᶜᵃ, ℑzᵃᵃᶜ, v, w) | |||
|
|||
S̅ₘ = ℑxyzᶜᶜᶜ(i, j, k, grid, ℑxyzᶠᶠᶠ, ℑxyzᶜᶜᶜ, ℑxyzᶠᶠᶠ, ϕ⁰⁵, ΣᵢⱼΣᵢⱼᶜᶜᶜ, u, v, w) |
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.
Currently the code goes into StackOverflowError
, likely due to the way the filter averaging is done as we might have function compositions which are too deep.
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.
Does it work if we use a simpler filter?
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.
we can maybe use a box filter here instead of all this combination of interpolations.
We can add a filter function to the struct
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.
Hmm. But this should not be an overflow error, right? Are we hitting some heuristic?
I would try combining steps to see what happens. For example you could define
ϕ⁰⁵_ΣᵢⱼΣᵢⱼᶜᶜᶜ(i, j, k, grid, u, v, w) = ϕ⁰⁵(i, j, k, grid, ΣᵢⱼΣᵢⱼᶜᶜᶜ, u, v, w)
You could also simply write the whole thing manually. With composition this deep, it might also make this code easier to understand.
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.
Does it work if we use a simpler filter?
What is complicated about this?
We should "Close #3637" with this one I think |
M₁₁ = 2Δᶠ * (S̅S̅₁₁ - α^2 * β^2 * S̅ₘ * S̅₁₁) | ||
M₂₂ = 2Δᶠ * (S̅S̅₂₂ - α^2 * β^2 * S̅ₘ * S̅₂₂) | ||
M₃₃ = 2Δᶠ * (S̅S̅₃₃ - α^2 * β^2 * S̅ₘ * S̅₃₃) | ||
M₁₂ = 2Δᶠ * (S̅S̅₁₂ - α^2 * β^2 * S̅ₘ * S̅₁₂) | ||
M₁₃ = 2Δᶠ * (S̅S̅₁₃ - α^2 * β^2 * S̅ₘ * S̅₁₃) | ||
M₂₃ = 2Δᶠ * (S̅S̅₂₃ - α^2 * β^2 * S̅ₘ * S̅₂₃) |
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.
Should this be
M₁₁ = 2Δᶠ * (S̅S̅₁₁ - α^2 * β^2 * S̅ₘ * S̅₁₁) | |
M₂₂ = 2Δᶠ * (S̅S̅₂₂ - α^2 * β^2 * S̅ₘ * S̅₂₂) | |
M₃₃ = 2Δᶠ * (S̅S̅₃₃ - α^2 * β^2 * S̅ₘ * S̅₃₃) | |
M₁₂ = 2Δᶠ * (S̅S̅₁₂ - α^2 * β^2 * S̅ₘ * S̅₁₂) | |
M₁₃ = 2Δᶠ * (S̅S̅₁₃ - α^2 * β^2 * S̅ₘ * S̅₁₃) | |
M₂₃ = 2Δᶠ * (S̅S̅₂₃ - α^2 * β^2 * S̅ₘ * S̅₂₃) | |
M₁₁ = 2Δᶠ * (S̅S̅₁₁ - α^2 * β * S̅ₘ * S̅₁₁) | |
M₂₂ = 2Δᶠ * (S̅S̅₂₂ - α^2 * β * S̅ₘ * S̅₂₂) | |
M₃₃ = 2Δᶠ * (S̅S̅₃₃ - α^2 * β * S̅ₘ * S̅₃₃) | |
M₁₂ = 2Δᶠ * (S̅S̅₁₂ - α^2 * β * S̅ₘ * S̅₁₂) | |
M₁₃ = 2Δᶠ * (S̅S̅₁₃ - α^2 * β * S̅ₘ * S̅₁₃) | |
M₂₃ = 2Δᶠ * (S̅S̅₂₃ - α^2 * β * S̅ₘ * S̅₂₃) |
?
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.
Can you paste in the reference that shows this?
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.
Taking a second look at things I now think there may be more typos than this one. So I suggest @xkykai and @simone-silvestri double-check this, but if I understand correctly, what's called 𝒥ᴿᴺ
in this PR is called $\mathcal J^{QN}$in Bou-Zeid et al. (2005), and here's its advection equation:
so using the language of this PR the forcing here should be
1 / T4Δ * (QᵢⱼNᵢⱼ - 𝒥ᴿᴺ)
instead of what's written below: 1 / TΔ * (LᵢⱼMᵢⱼ - 𝒥ᴿᴺ)
.
And the functions
Similar comments are valid for the function below (𝒥ᴺᴺ_forcing_function()
).
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.
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.
The difference between Q and L (and M and N) is the filter size. The stresses for the 𝒥ᴿᴺ
forcings are averaged twice as much as the 𝒥ᴸᴹ
forcings (if you look at how the averages are calculated). However, I would say that to push this PR forward we need to:
- define an averaging operators (to be held in the closure struct) for the
M - L
fluxes and for theR - N
fluxes - remove all this combination of interpolations in favor of those averaging operators
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.
The difference between Q and L (and M and N) is the filter size.
Agreed. The
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.
What do the tilde, hat, and bar mean?
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.
- Tilde: LES-filtered velocity. In our case it's simply the velocities that come out of
model.velocities
- Bar: First test filter
- Hat: Second test filter (at a larger spatial scale than the first)
M₁₁ = 2Δᶠ * (S̅S̅₁₁ - α^2 * β^2 * S̅ₘ * S̅₁₁) | ||
M₂₂ = 2Δᶠ * (S̅S̅₂₂ - α^2 * β^2 * S̅ₘ * S̅₂₂) | ||
M₃₃ = 2Δᶠ * (S̅S̅₃₃ - α^2 * β^2 * S̅ₘ * S̅₃₃) | ||
M₁₂ = 2Δᶠ * (S̅S̅₁₂ - α^2 * β^2 * S̅ₘ * S̅₁₂) | ||
M₁₃ = 2Δᶠ * (S̅S̅₁₃ - α^2 * β^2 * S̅ₘ * S̅₁₃) | ||
M₂₃ = 2Δᶠ * (S̅S̅₂₃ - α^2 * β^2 * S̅ₘ * S̅₂₃) |
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.
Same comment here
M₁₁ = 2Δᶠ * (S̅S̅₁₁ - α^2 * β^2 * S̅ₘ * S̅₁₁) | |
M₂₂ = 2Δᶠ * (S̅S̅₂₂ - α^2 * β^2 * S̅ₘ * S̅₂₂) | |
M₃₃ = 2Δᶠ * (S̅S̅₃₃ - α^2 * β^2 * S̅ₘ * S̅₃₃) | |
M₁₂ = 2Δᶠ * (S̅S̅₁₂ - α^2 * β^2 * S̅ₘ * S̅₁₂) | |
M₁₃ = 2Δᶠ * (S̅S̅₁₃ - α^2 * β^2 * S̅ₘ * S̅₁₃) | |
M₂₃ = 2Δᶠ * (S̅S̅₂₃ - α^2 * β^2 * S̅ₘ * S̅₂₃) | |
M₁₁ = 2Δᶠ * (S̅S̅₁₁ - α^2 * β * S̅ₘ * S̅₁₁) | |
M₂₂ = 2Δᶠ * (S̅S̅₂₂ - α^2 * β * S̅ₘ * S̅₂₂) | |
M₃₃ = 2Δᶠ * (S̅S̅₃₃ - α^2 * β * S̅ₘ * S̅₃₃) | |
M₁₂ = 2Δᶠ * (S̅S̅₁₂ - α^2 * β * S̅ₘ * S̅₁₂) | |
M₁₃ = 2Δᶠ * (S̅S̅₁₃ - α^2 * β * S̅ₘ * S̅₁₃) | |
M₂₃ = 2Δᶠ * (S̅S̅₂₃ - α^2 * β * S̅ₘ * S̅₂₃) |
I'm curious as to why you picked |
This is also not super clean because the forcing functions for the additional tracers are added manually to the model. |
I believe what we are doing here is using two filter scales |
Hmm, then I'm confused. When you assume |
I think you're correct here! Sorry for the confusion here, but I suppose by scale-invariance I mean |
Ah, I see, I was under the impression you were trying to implement the scale-invariant version, but it does make sense to if you're implementing the scale-dependent version. |
Pr=0.7 | ||
Ri = 0.5 | ||
Ni=10 | ||
end_time=1000 |
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.
What is going on here? Isn't there already a script for invoking the utilities in this script?
@@ -113,7 +125,7 @@ function simulate_stratified_couette_flow(; Nxy, Nz, arch=GPU(), h=1, U_wall=1, | |||
##### Impose boundary conditions | |||
##### | |||
|
|||
grid = RectilinearGrid(arch, size = (Nxy, Nxy, Nz), extent = (4π*h, 2π*h, 2h)) | |||
grid = RectilinearGrid(arch, size = (Nxy, Nxy, Nz), extent = (4π*h, 2π*h, 2h), halo = (6, 6, 6)) |
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.
grid = RectilinearGrid(arch, size = (Nxy, Nxy, Nz), extent = (4π*h, 2π*h, 2h), halo = (6, 6, 6)) | |
grid = RectilinearGrid(arch; size = (Nxy, Nxy, Nz), extent = (4π*h, 2π*h, 2h), halo) |
make this cleaner by adding halo
as an argument to simulate_stratified_couette_flow
.
Also, it doesn't look like the closure
is an argument to simulate_stratified_couette_flow
. You'll need that too. (You can also infer the halo size.)
Just as a general tip, I think you will save time if you generalize these functions first. Now, you are in the position of having to 1) walk back the changes you made and then 2) implement an interface that allows different closures. This is actually more work then if you had simply done (2) to begin with.
I suggest implementing the tracer-specific forcing in a similar manner that we do for CATKE and k-epsilon |
Closes #3637
This is an implementation of the scale-dependent Lagrangian-averaged dynamic Smagorinsky model as outlined in section C III. in Bou-Zeid et al. 2005.
@simone-silvestri @tomchor