# Best practices for flattening and reconstructing nested structs for ODEs, Solve, Kalman.jl etc

**URL:** <https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093>\
**Category:** Modelling & Simulations\
**Created:** [May 17, 2025, 12:59pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093 "2025-05-17T12:59:36Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![stevenhughes](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@stevenhughes](https://discourse.julialang.org/u/stevenhughes)\
**Post date:** [May 17, 2025, 12:59pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093/1 "2025-05-17T12:59:36Z")

</div>

Hello All,

I’m prototyping a space/astrodynamics simulation and optimization framework in Julia. For the user interface, the most intuitive way to encapsulate all the data is on structs. Below is a toy example which is far simpler than many use cases, but hopefully gets the point across.

```julia
struct CartesianState
    rv::SVector{3, Float64}
    vv::SVector{3, Float64}
end

struct Spacecraft
    state::CartesianState
    mass::Float64
end

struct ForceModel
    mu::Float64
    Cd::Float64
end

```

Now my question. I need a way to efficiently create “flat” state/optimization vectors for DifferentialEquations.jl., solve(), JuMP, Kalman.jl and other packages. If a user specifies Spacecraft.CartesianState and ForceModel.mu as problem variables (this is truly a toy, real problems are substantially more complicated), I need a fast, clean way to construct a vector from those fields for initializing ODEs, solvers, and a way to map vectors from those systems back to the structs in the sim system to evaluate ODE values, optimization functions etc. I need a way do this that is agnostic to package interface (solve(), JuMP, Kalman.jl, DifferentialEquations.jl) so unless I am missing an existing, elegant solution, I need to handle the “bookkeeping” on my end.

I’ve looked at ComponentArrays.jl, and `Accessors.jl` ad other packages, and they don’t seem to quite solve this problem. I’ve rolled my own and it works OK for a simple problem, but, doesn’t scale well for structs with nested composition . Unless I am missing something, there is not a canonical solution to this problem. Am I missing a package out there that solves this generally and efficiently? If there is no existing solution, any advise on how to tackle this problem?

---

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [May 17, 2025, 1:06pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093/2 "2025-05-17T13:06:51Z")

</div>

I don’t have an answer to your actual question, but I just want to point out that `struct Spacecraft` is an abstract container, so you may want to turn it into a parametrized struct (`struct Spacecraft{T<:CartesianState}` and then `state::T`) to avoid getting a performance hit.

---

<div class="post-metadata">

**Author:** ![stevenhughes](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@stevenhughes](https://discourse.julialang.org/u/stevenhughes)\
**Post date:** [May 17, 2025, 1:09pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093/3 "2025-05-17T13:09:50Z")

</div>

Yep. Thanks. I learned that lesson recently and am converting my structs to use that approach for efficiency.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 17, 2025, 2:55pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093/4 "2025-05-17T14:55:21Z")

</div>

NamedArrayPartition from RecursiveArrayTools?

---

<div class="post-metadata">

**Author:** ![stevenhughes](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@stevenhughes](https://discourse.julialang.org/u/stevenhughes)\
**Post date:** [May 17, 2025, 3:19pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093/5 "2025-05-17T15:19:03Z")

</div>

Thanks. I tried a few approaches over the last month, and I can’t remember if I tried those tools. I’ll see if that works and post back here.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [May 17, 2025, 9:24pm UTC](https://discourse.julialang.org/t/best-practices-for-flattening-and-reconstructing-nested-structs-for-odes-solve-kalman-jl-etc/129093/6 "2025-05-17T21:24:19Z")

</div>

Try this:

```julia
obj = your arbitrary object

using AccessorsExtra

nums = getall(obj, RecursiveOfType(Number))
# nums is a flat collection of numbers
# ... do some manipulation with nums ...
newobj = setall(obj, RecursiveOfType(Number), nums)

```

Supports arbitrary structs, and more complex/fine-grained manipulations as well.
