# Projecting u during propagation

**URL:** <https://discourse.julialang.org/t/projecting-u-during-propagation/129663>\
**Category:** General Usage\
**Tags:** differentialequation\
**Created:** [June 5, 2025, 7:42am UTC](https://discourse.julialang.org/t/projecting-u-during-propagation/129663 "2025-06-05T07:42:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![diffeqslvr](https://avatars.discourse-cdn.com/v4/letter/d/f475e1/32.png) [@diffeqslvr](https://discourse.julialang.org/u/diffeqslvr)\
**Post date:** [June 5, 2025, 7:42am UTC](https://discourse.julialang.org/t/projecting-u-during-propagation/129663/1 "2025-06-05T07:42:44Z")

</div>

I am solving a set of equations of motion that I know is only approximate and will lead to unphysical results. After each propagation step, I want to project `u` back onto a physical subspace.

I was wondering if something like this is possible using `Tsit5` of the DifferentialEquations module. I have heard that one should not change `u` manually during propagation and wanted to make sure that what I am doing is not leading to unexpected results. For example, I am unsure whether `Tsit5()` uses the projected values of `u` to calculate the next update or whether it uses the values before the projection.

My code looks something like this:

```julia
function always(u, t, integrator)
    return true
end

function projection_func!(slv::Solve.Instance)
    return function (integrator)
        # modify u here
        project!(
            integrator.u, 
            max_steps = slv.n_project_max, 
        )
    end
end

function solve_projected(slv, u₀, p)
    cb = DiscreteCallback(always, projection_func!(slv))

    # Do time evolution
    prob = ODEProblem(eoms!, u₀, slv.tspan, p)
    sol = solve(
        prob,
        Tsit5(),
        callback = cb,
        dtmax = slv.dtmax,
        maxiters = slv.maxiters,
        reltol = slv.reltol,
        abstol = slv.abstol,
        saveat = slv.saveat,
    )
    return sol
end

```

---

<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:** [June 5, 2025, 9:46am UTC](https://discourse.julialang.org/t/projecting-u-during-propagation/129663/2 "2025-06-05T09:46:42Z")

</div>

Check ManifoldProjection in DiffEqCallbacks.jl.

> **[Manifold Projection · DiffEqCallbacks.jl](https://docs.sciml.ai/DiffEqCallbacks/stable/projection/)**
>
> Documentation for DiffEqCallbacks.jl.

Or for a lot more detail on this topic:

> **[Machine learning with hard constraints: Neural Differential-Algebraic...](https://www.stochasticlifestyle.com/machine-learning-with-hard-constraints-neural-differential-algebraic-equations-daes-as-a-general-formalism/)**
>
> We recently released a new manuscript Semi-Explicit Neural DAEs: Learning Long-Horizon Dynamical Systems with Algebraic Constraints where we showed a way to develop neural networks where any arbitrary constraint function can be directly imposed...

---

<div class="post-metadata">

**Author:** ![diffeqslvr](https://avatars.discourse-cdn.com/v4/letter/d/f475e1/32.png) [@diffeqslvr](https://discourse.julialang.org/u/diffeqslvr)\
**Post date:** [June 5, 2025, 12:53pm UTC](https://discourse.julialang.org/t/projecting-u-during-propagation/129663/3 "2025-06-05T12:53:11Z")

</div>

Thanks for the helpful ressources! The manifold projection is definitely something I will consider.

But coming back to my original question: Will my approach with `Tsit5()` work in principle? Or is what I am doing “evil” in the sense that the solver does not expect it?

---

<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:** [June 5, 2025, 1:00pm UTC](https://discourse.julialang.org/t/projecting-u-during-propagation/129663/4 "2025-06-05T13:00:00Z")

</div>

Nothing wrong there, just set `save_positions` correctly and know that the projection will mean that you only can get linear interpolations
