-
Notifications
You must be signed in to change notification settings - Fork 236
Flip location along accumulating dimension for Accumulating
scans
#4358
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
base: main
Are you sure you want to change the base?
Conversation
I think so! Can you point me to the accumulations we currently support? Should be hard to consider them one by one.
Not sure. Maybe at least a warning?
I'd say a unit test at least. It also shouldn't be hard to cook up a quantitative example with regular and stretched grids. Something along the lines of julia> cumsum(a);
julia> cumsum(a) == [i for i in 1:4]
true ? I can help you out with this if you want.
Possibly testing subsequent accumulations over different dimensions? i.e. accumulating over |
Please take a look at the code modified by this PR, it's all in that file.
I'd greatly appreciate help!
Maybe this can be easily tested with an array full of 1s. |
Tests fail because this PR actually changes the meaning of the accumulations. Now we are tasked with defining the first element of the accumulation. For a cumsum this is 0, but other accumulating reductions (which may be invoked rarely, who knows) require other choices, which I believe are equivalent to the neutral element / mask that is used. |
To be clear, you're talking about adding more of these methods?: neutral_element(::typeof(Base.add_sum), T) = convert(T, 0) |
I'm a bit confused about some of the behavior though. Taking one of the tests as an example, you define infil> interior(T, :, 1, 1)
2-element view(::Array{Float64, 3}, 3:4, 3, 3) with eltype Float64:
1.5
2.5 And then you define an x-accumulation of 2-element view(::Array{Float64, 3}, 3:4, 3, 3) with eltype Float64:
0.0
2.5 This doesn't really make sense to me. I expected the two elements to be |
Let's think about this. I think it depends on the location of the parent field. If we integrate a Center field and we store the result at interfaces, then the first value represents the integral computed over no points, so its 0. Therefore I expect T = [1.5, 2.5]
cumint_T = [0, 1.5, 4.0] This seems right to me and also has the property that the derivative returns you the original array. If we integrate a Face field, I think that index 1 stores the first value, not the neutral value. For example cum_int_T = [0, 1.5, 4] # at Face
double_int_T = [1.5, 5.5] # at Center That's my thought. Does this make sense? |
That makes perfect sense, and it was my thought as well. However, the current behavior is that when cumulatively integrating over a periodic dimension, faces and center grids have the same size. I believe we also need to change this behavior then for this to make sense, no? |
Are you sure? Changing the location should change the size. |
Not on periodic dimensions: julia> grid = RectilinearGrid(size=(4, 4, 4), extent=(1, 1, 1));
julia> T = CenterField(grid)
4×4×4 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 4×4×4 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── boundary conditions: FieldBoundaryConditions
│ └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: ZeroFlux
└── data: 10×10×10 OffsetArray(::Array{Float64, 3}, -2:7, -2:7, -2:7) with eltype Float64 with indices -2:7×-2:7×-2:7
└── max=0.0, min=0.0, mean=0.0
julia> Field(CumulativeIntegral(T, dims=1))
4×4×4 Field{Face, Center, Center} on RectilinearGrid on CPU
├── data: OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, size: (4, 4, 4)
├── grid: 4×4×4 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── operand: CumulativeIntegral of BinaryOperation at (Center, Center, Center) over dims 1
├── status: time=0.0
└── data: 10×10×10 OffsetArray(::Array{Float64, 3}, -2:7, -2:7, -2:7) with eltype Float64 with indices -2:7×-2:7×-2:7
└── max=0.0, min=0.0, mean=0.0 It does work for nonperiodic dimensions though: julia> Field(CumulativeIntegral(T, dims=3))
4×4×5 Field{Center, Center, Face} on RectilinearGrid on CPU
├── data: OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, size: (4, 4, 5)
├── grid: 4×4×4 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── operand: CumulativeIntegral of BinaryOperation at (Center, Center, Center) over dims 3
├── status: time=0.0
└── data: 10×10×11 OffsetArray(::Array{Float64, 3}, -2:7, -2:7, -2:8) with eltype Float64 with indices -2:7×-2:7×-2:8
└── max=0.0, min=0.0, mean=0.0 |
Center and Face have the same size on Periodic dimensions. Also, I am confused whether this makes sense in a Periodic direction. As an example, |
Yes, I guess I haven't been expressing myself very clearly, but that has been precisely my point in these last few comments. The way we treat periodic directions doesn't work well with integrals. |
Okay, but you are implying we are doing something wrong. My last question asks: is |
afaik there's no problem in defining a I think the trouble for us is that So maybe we need to create a different abstraction to deal with cumulative integrals that is sized differently? Not sure... Hopefully things are a bit clearer now. |
The problem is that integral of |
I'm aware. What I'm advocating for is that integrals of periodic |
What topology would you use? How would you fill the halos of this new topology? What system of rules will be used to change between "related topologies" upon differentiation and integration? For example, the derivative of a Bounded field is not Periodic. Are you proposing to create a NonPeriodicIntegrated topology or something like that? What is a concrete example of some valid mathematical / physical object that this could be used for? |
I don't know how to answer all those questions. I'm not that fast with software design. My only point is that it's definitely possible numerically. That said, given your questions, it's probably be beyond the scope of this PR. Should we just throw an error when integrating over Periodic dimensions for now? |
Yes. I am also skeptical that one should pursue an abstraction for "integrals of Periodic functions that are not themselves Periodic". |
I think you're right, so we need cum_int_T = [0, 1.5, 4] # at Face
double_int_T = [0, 1.5] # at Center right? And to satisfy the first boundary value, we'd in principle need 5.5 on the first halo point |
Addresses #4354
Things to think about:
Nothing
)cc @tomchor