# How to update the initial condition in DifferentialEquations?

**URL:** https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696
**Category:** General Usage
**Tags:** diffeq
**Created:** [December 25, 2019, 3:06pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696 "2019-12-25T15:06:53Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![fedoroff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedoroff/32/53209_2.png) [@fedoroff](https://discourse.julialang.org/u/fedoroff)
#### Post date: [December 25, 2019, 3:06pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/1 "2019-12-25T15:06:53Z")

</div>

Hello!

I try to solve a nonlinear differential equation using a split-step method.  
The right hand side of my equation has two terms:

\frac{du}{dt} = f(u,t) + g(u,t)

According to the split-step method, I can split every integration step (t\_n, t\_n+dt) into two (t\_n, t\_n+dt/2) and (t\_n+dt/2,t\_n+dt), and then replace the solution of the whole equation by a consecutive solution of the following equations:

\begin{align} & \frac{du}{dt} = f(u,t), \qquad t\in\left(t\_n,t\_n+\frac{dt}{2}\right)\\ & \frac{du}{dt} = g(u,t), \qquad t\in\left(t\_n+\frac{dt}{2},t\_n+dt\right) \end{align}

The first equation takes u(t\_n) as the initial condition and calculates u(t\_n+dt/2). In turn, the second equation takes u(t\_n+dt/2) as the initial condition and calculates u(t\_n+dt). To solve the first equation I use my own method, but for the second one I want to use DIfferentialEquations. However, in the split-step method I have to change the initial condition of the problem on each step. But redefining the whole problem on each step is too costly. Therefore, I search for a method where I can define the problem once and then update the initial condition on demand.

So far, I think to use the integrators interface. Something like this:

```julia
using OrdinaryDiffEq

function g(du, u, p, t)
    @inbounds @. du = u
    return nothing
end

# Define the problem:
tspan = (0., 10.)
u0 = ones(100)
prob = ODEProblem(g, u0, tspan)
integrator = OrdinaryDiffEq.init(prob, BS3(), dense=false)

# Main loop:
Nt = 100
dt = (tspan[2] - tspan[1]) / Nt
u = copy(u0) # solution which is updated at each step
for i=1:Nt
    # First half-step of the split-step method:
    @. u = u + 0.01 # dummy example

    # Second half-step of the split-step method:
    @. integrator.u = u # set the new initial condition?
    # @. integrator.uprev = u # for some reason, this does not work
    step!(integrator, dt/2, true)
    @. u = integrator.u # update the solution
end

```

However, are there any canonical method to update the initial condition?  
Or may be there is some in-place solve method, which can use the original initial condition array u0 and update it with the solution on each step?

Thank you.

---

<div class="post-metadata">

### Author: ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)
#### Post date: [December 25, 2019, 3:31pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/2 "2019-12-25T15:31:55Z")

</div>

Look at Callbacks in the DiffEq manuals, maybe the Discrete Time callback can be adapted for this purpose.

---

<div class="post-metadata">

### Author: ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)
#### Post date: [December 25, 2019, 3:36pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/3 "2019-12-25T15:36:51Z")

</div>

I was thinking of PeriodicCallback but there may be several ways to do what you want.

---

<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: [December 25, 2019, 7:13pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/4 "2019-12-25T19:13:55Z")

</div>

A DiscreteCallback where the condition is fixed to true will fire after each step, and you can use this to do what you need to do

---

<div class="post-metadata">

### Author: ![fedoroff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedoroff/32/53209_2.png) [@fedoroff](https://discourse.julialang.org/u/fedoroff)
#### Post date: [December 25, 2019, 8:29pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/5 "2019-12-25T20:29:41Z")

</div>

But what should be the affect function?  
Like this?

```julia
affect!(integrator) = @. integrator.u = u

```

where u is the current solution which I want to be the initial condition.

---

<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: [December 25, 2019, 8:39pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/6 "2019-12-25T20:39:07Z")

</div>

Yup that’s it.

---

<div class="post-metadata">

### Author: ![fedoroff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedoroff/32/53209_2.png) [@fedoroff](https://discourse.julialang.org/u/fedoroff)
#### Post date: [December 25, 2019, 8:52pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/7 "2019-12-25T20:52:02Z")

</div>

Thank you.

Just the last question. The code with the discrete callback will be equivalent to the code from the first post:

```julia
for i=1:Nt
    # modify u
    @. integrator.u = u
    step!(integrator, dt, true)
end

```

Is it correct?

---

<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: [December 25, 2019, 8:59pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/8 "2019-12-25T20:59:16Z")

</div>

No, that’ll actually use the stepping, i.e. be calling the ODE steps. I think you just want to update `u` and then `integrator.t += integrator.dt` manually. Then let it do its next step.

---

<div class="post-metadata">

### Author: ![fedoroff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedoroff/32/53209_2.png) [@fedoroff](https://discourse.julialang.org/u/fedoroff)
#### Post date: [January 9, 2020, 2:19pm UTC](https://discourse.julialang.org/t/how-to-update-the-initial-condition-in-differentialequations/32696/9 "2020-01-09T14:19:11Z")

</div>

Just for completeness, an identical question from a previous discussion: [https://discourse.julialang.org/t/efficient-way-to-handle-operator-splitting-periodically-updating-solution-mid-solve-in-juliadiffeq/30757/1](https://discourse.julialang.org/t/efficient-way-to-handle-operator-splitting-periodically-updating-solution-mid-solve-in-juliadiffeq/30757/1)
