Conversation
Review checklistThis checklist is meant to assist creators of PRs (to let them know what reviewers will typically look for) and reviewers (to guide them in a structured review process). Items do not need to be checked explicitly for a PR to be eligible for merging. Purpose and scope
Code quality
Documentation
Testing
Performance
Verification
Created with ❤️ by the Trixi.jl community. |
jlchan
left a comment
There was a problem hiding this comment.
Hi @ShahuK283! Thanks for the PR; I just replied to the discussion in #1717, and lean towards plain Vector{<:StructArray} return types. I'm happy to do StructArrays if @ranocha or @sloede prefer though.
d7ee1bd to
badf9c4
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2854 +/- ##
==========================================
+ Coverage 97.04% 97.11% +0.06%
==========================================
Files 605 608 +3
Lines 47303 47308 +5
==========================================
+ Hits 45905 45940 +35
+ Misses 1398 1368 -30
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hi! All CI checks have passed except for format-suggestion and Codecov. I believe this is because the new get_u and get_coordinates functions aren't being called anywhere in the test suite yet. I have a quick test ready to verify them: Test nodal APIsol = solve(ode, dt=1.0, maxiters=1) Before I add this, I wanted to ask what the preferred approach is: |
|
I think you can call an existing elixir to get a valid `sol` object. I believe some other tests for
visualization do so?
…On Fri, Mar 13, 2026 at 12:48 PM ShahuK283 ***@***.***> wrote:
*ShahuK283* left a comment (trixi-framework/Trixi.jl#2854)
<#2854 (comment)>
Hi! All CI checks have passed except for format-suggestion and Codecov. I
believe this is because the new get_u and get_coordinates functions aren't
being called anywhere in the test suite yet.
I have a quick test ready to verify them:
Test nodal API
sol = solve(ode, dt=1.0, maxiters=1)
@test <https://github.com/test> size(Trixi.get_u(sol)) == (1, 4, 4, 256)
@test <https://github.com/test> size(Trixi.get_coordinates(sol)) == (2,
4, 4, 256)
Before I add this, I wanted to ask what the preferred approach is:
Should I append these lines to an existing file (like
test/test_tree_2d_advection.jl) to reuse an existing sol object, or would
you prefer I create a new dedicated test file for the API?
—
Reply to this email directly, view it on GitHub
<#2854 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAI2HUCX237US62ICHGN4VD4QRCW5AVCNFSM6AAAAACWMHUVJKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DANJWHA4TKMZTGI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
Hi @jlchan, I have updated the dimensions to correctly match with the variables in SVector. I also added the Nodal API tests in test_tree_2d_advection.jl using the existing elixir as you suggested, and checked for formatting errors. |
jlchan
left a comment
There was a problem hiding this comment.
Looks good, just had a few questions. Also, I'm partial to just using plain Vector{<:SVector} instead of StructArrays if that's simpler.
src/auxiliary/solution_interface.jl
Outdated
| end | ||
|
|
||
| function get_coordinates(semi::AbstractSemidiscretization) | ||
| x_raw = semi.cache.elements.node_coordinates |
There was a problem hiding this comment.
I don't think this works for all Semidiscretization types; it might be good to dispatch using mesh_equations_solver_cache and then specialize on the solver or mesh type. For example, it doesn't work with DGMulti
There was a problem hiding this comment.
added multiple dispatch in get_coordinates via mesh_equations_solver_cache(semi) to route coordinate extraction.
It returns cache.elements.node_coordinates for standard meshes and mesh.md.xyz for DGMultiMesh.
test/test_tree_2d_advection.jl
Outdated
| @test size(Trixi.get_u(sol)) == (4, 4, 256) | ||
| @test size(Trixi.get_coordinates(sol)) == (4, 4, 256) |
There was a problem hiding this comment.
Might be good to also add a test that the retrieved values are correct.
There was a problem hiding this comment.
We should also add more tests for other mesh types.
There was a problem hiding this comment.
I added the Nodal API test suites to cover TreeMesh, StructuredMesh, UnstructuredMesh, and DGMulti. The tests now verify exact value correctness (e.g., @test coords == semi.cache.elements.node_coordinates) rather than just checking dimensions.
src/auxiliary/solution_interface.jl
Outdated
| function get_u(u_ode, semi::AbstractSemidiscretization) | ||
| u_raw = wrap_array(u_ode, semi) | ||
| n_vars = nvariables(semi) | ||
| @assert ndims(u_raw)>=3 "Unexpected wrap_array shape: $(size(u_raw))" |
There was a problem hiding this comment.
What is this guarding against?
src/auxiliary/solution_interface.jl
Outdated
| function get_u(sol) | ||
| semi = sol.prob.p | ||
| u_ode = sol.u[end] | ||
| return get_u(u_ode, semi) | ||
| end | ||
|
|
||
| function get_u(u_ode, semi::AbstractSemidiscretization) | ||
| u_raw = wrap_array(u_ode, semi) |
There was a problem hiding this comment.
These are the two methods that should be documented (get a docstring). We should also mention them briefly in the documentation, e.g., introduce a new subsection "Custom visualization" in https://trixi-framework.github.io/TrixiDocumentation/stable/visualization/ and mention these methods there together with an example.
src/Trixi.jl
Outdated
| using SparseArrays: AbstractSparseMatrix, AbstractSparseMatrixCSC, sparse, droptol!, | ||
| rowvals, nzrange, nonzeros | ||
|
|
||
| using StructArrays |
There was a problem hiding this comment.
We already load the package below: @reexport using StructArrays: StructArrays, StructArray.
There was a problem hiding this comment.
Thanks! I missed that. I had fixed it in this commit
test/test_tree_2d_advection.jl
Outdated
| @test size(Trixi.get_u(sol)) == (4, 4, 256) | ||
| @test size(Trixi.get_coordinates(sol)) == (4, 4, 256) |
There was a problem hiding this comment.
We should also add more tests for other mesh types.
jlchan
left a comment
There was a problem hiding this comment.
Thank you! It's looking good, I have a few suggestions for organization. When moving the tests to test_visualization.jl it would also be nice if we could consolidate them into a loop over a single test since some of the visualization tests are identical.
|
|
||
| If you want to extract the raw nodal coordinates and solution arrays to build your own custom plots or perform external data analysis, you can use the `get_coordinates` and `get_u` functions. | ||
|
|
||
| These functions use multiple dispatch to automatically reshape the flat ODE state vectors into intuitive, multidimensional tensors based on the underlying mesh type. |
There was a problem hiding this comment.
I think the "multidimensional tensors" comment is true for TreeMesh, not DGMultiMesh
| coords = Trixi.get_coordinates(sol) | ||
| u_nodal = Trixi.get_u(sol) | ||
|
|
||
| # The arrays are now ready to be used with external tools like Makie.jl or Plots.jl |
There was a problem hiding this comment.
Could you include an example of a Plots.jl command?
| function get_coordinates(mesh, equations, solver, cache) | ||
| return cache.elements.node_coordinates | ||
| end | ||
|
|
There was a problem hiding this comment.
Can you add a comment about the layout of the coordinates for TreeMesh vs DGMultiMesh?
| @testset "Nodal API" begin | ||
| trixi_include(@__MODULE__, | ||
| joinpath(examples_dir(), "tree_2d_dgsem", "elixir_advection_basic.jl")) | ||
|
|
||
| semi = sol.prob.p | ||
|
|
||
| coords = Trixi.get_coordinates(sol) | ||
| @test size(coords) == (2, 4, 4, 256) | ||
| @test coords == semi.cache.elements.node_coordinates | ||
|
|
||
| u_nodal = Trixi.get_u(sol) | ||
| @test size(u_nodal) == (1, 4, 4, 256) | ||
| @test u_nodal == Trixi.wrap_array(sol.u[end], semi) | ||
| end | ||
|
|
There was a problem hiding this comment.
Can you move this to test_visualization.jl instead?
|
|
||
| @testset "Nodal API" begin | ||
| coords = Trixi.get_coordinates(sol) | ||
| @test size(coords) == size(semi.cache.elements.node_coordinates) | ||
| @test coords == semi.cache.elements.node_coordinates | ||
|
|
||
| u_nodal = Trixi.get_u(sol) | ||
| @test size(u_nodal) == size(Trixi.wrap_array(sol.u[end], semi)) | ||
| @test u_nodal == Trixi.wrap_array(sol.u[end], semi) | ||
| end |
There was a problem hiding this comment.
Can you move this to test_visualization.jl instead?
|
|
||
| @testset "Nodal API" begin | ||
| coords = Trixi.get_coordinates(sol) | ||
| @test size(coords) == size(semi.cache.elements.node_coordinates) | ||
| @test coords == semi.cache.elements.node_coordinates | ||
|
|
||
| u_nodal = Trixi.get_u(sol) | ||
| @test size(u_nodal) == size(Trixi.wrap_array(sol.u[end], semi)) | ||
| @test u_nodal == Trixi.wrap_array(sol.u[end], semi) | ||
| end |
There was a problem hiding this comment.
Can you move this to test_visualization.jl instead?
|
|
||
| @testset "Nodal API" begin | ||
| semi = sol.prob.p | ||
|
|
||
| coords = Trixi.get_coordinates(sol) | ||
| @test coords == semi.mesh.md.xyz | ||
|
|
||
| u_nodal = Trixi.get_u(sol) | ||
| @test size(u_nodal) == size(Trixi.wrap_array(sol.u[end], semi)) | ||
| @test u_nodal == Trixi.wrap_array(sol.u[end], semi) | ||
| end |
There was a problem hiding this comment.
Can you move this to test_visualization.jl instead?
Hi @jlchan, @ranocha, and @sloede,
Thanks for the great discussion on #1717! I've opened this Draft PR with a prototype that returns StructArrays of SVectors. It uses ntuple and views over Trixi's internal wrap_array to collapse the n_vars dimension with zero allocations, yielding purely spatial arrays.
@jlchan - Does this StructArray format align well with your usual workflows?
For now, I have just added the foundational extraction API (get_u and get_coordinates). If this approach looks right to everyone, Michael's wishlist for spatial interpolation can be done next in a separate PR!
Let me know what you think