How to save ODE solution only at the last step while using Callbacks in Julia

185 views Asked by At

I am solving the following ode, using Julia. The code I am using is as follows:

   using DelimitedFiles
   using LinearAlgebra 
   using Random
   using Distributions
   using DifferentialEquations
   using Plots

   N = 100
   σ, a, J, K = 10.0, 1.0,1.0,1.0
   ω = zeros(N); 

   function heaviside(x::Real)
        return x >= 0.0 ? 1.0 : 0.0
   end


   function rhs(du,u,p,t)

    u1 = @view u[1:N]
    du1 = @view du[1:N]
    u2 = @view u[N+1:2*N]
    du2 = @view du[N+1:2*N]
 
    σ,a,J,K=p

   for i in 1:N
    du1[i]=(1/N)*sum(j->((u1[j]-u1[i])*(1+J*cos(u2[j]-u2[i]))-sign(u1[j]-u1[i])),1:N)
    
    du2[i]=(ω[i]) + (K/N)* sum(j->(sin(u2[j]-u2[i])*(1-(u1[j]-u1[i])^2/ 
  σ^2)*heaviside(σ - abs((u1[j]-u1[i])))),1:N)
  end


    return du 

  end


  ti=0
  tf=500
  tt=0.75*tf
  tspan = (ti, tf)  # Assuming you want to integrate from 0 to T
  dts=0.25
  vector_t=tt:dts:tf
  p=[σ,a,J,K]
  Random.seed!(123)
  u0= [(rand() * 8.0 - 4.0, rand() * (2.0 * π) - π) for j in 1:N]
  u0=vcat([x[1] for x in u0], [x[2] for x in u0]);

  prob = ODEProblem(rhs,u0, tspan,p);


      # For making mean_u1 zero
      function condition(u,t,integrator)
       t == integrator.t
      end

      function affect!(integrator)

      u1_mean = mean(integrator.u[1:N])
      integrator.u[1:N] .-= u1_mean
      end

      cbd = DiscreteCallback(condition, affect!)

    ##################################
  saved_values2= SavedValues(Float64,ComplexF64)
   function saver2(u,t,integrator)
       _pp=u[1:N]
       _qq=u[N+1:2*N]
      out2= mean((_pp).*exp.((_qq)*1im))
   end
 cb2 = SavingCallback(saver2, saved_values2,saveat=tt:dts:tf) 
 ###################################

  ###################################

   saved_values4= SavedValues(Float64,Float64)
 function saver4(u,t,integrator)
       duc=rhs(zeros(size(u)),u,integrator.p,t)
        _pp=duc[1:N]
       _qq=duc[N+1:2*N]
    out4= mean(sqrt.(((_pp).^2)+((_qq).^2)))
 end
cb4 = SavingCallback(saver4, saved_values4,saveat=tt:dts:tf)
 #####################################

   cbs = CallbackSet(cbd, cb2,cb4);

    @time sol= solve(prob, Tsit5(),reltol=1e-6,maxiters=1e20, callback = cbs,saveat= 
      [tf]);


      sizeof(sol)

      saved_values4.saveval
      print(mean(saved_values4.saveval));



       Z1=saved_values2.saveval;
       vel=saved_values4.saveval;

So in the above code I am making the mean of u1 variable zero after each integration step using DiscreteCallback, and then I am using SavingCallback to store two measures Z1 and vel from the integration within the time range tt:dts:tf, therefore the in SavingCallback function I have added the saveat=tt:dts:tf. So, I don't need the whole solution given by sol after the integration and only need the solution at the last time. That's why I have used the saveat=[tf] there. But even after doing this the integration is saving the solution for all the steps. So can anyone suggest me why this is happening and also how to overcome this, because saving the sol taking much space and making my machine very slow.

1

There are 1 answers

4
max xilian On

With regards to your problem, when you want the SavingCallback to only save at the last time step, then you also have to use only this last time step at the saveat of the SavingCallback, not (only) of the solve command. Currently you provide the SavingCallback with the instruction to save at tt:dts:tf