在 Julia 中使用回调时如何仅在最后一步保存 ODE 解决方案

问题描述 投票:0回答:1

我正在使用 Julia 解决以下颂歌。我使用的代码如下:

   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;

因此,在上面的代码中,我使用 DiscreteCallback 在每个积分步骤后将 u1 变量的平均值设为零,然后使用 SavingCallback 来存储时间范围 tt:dts:tf 内积分的两个测量值 Z1 和 vel,因此在 SavingCallback 函数中,我添加了 saveat=tt:dts:tf。 所以,我不需要积分后sol给出的整个解,只需要最后一次的解。这就是为什么我在那里使用了 saveat=[tf] 。但即使在执行此操作之后,集成也会保存所有步骤的解决方案。那么任何人都可以建议我为什么会发生这种情况以及如何克服这个问题,因为节省溶胶占用大量空间并使我的机器非常慢。

julia ode differentialequations.jl
1个回答
0
投票

请仅发布最少的、可重现的示例,请参阅 https://stackoverflow.com/help/minimal-reproducible-example 获取解释。

关于你的问题,当你希望

SavingCallback
仅在最后一个时间步保存时,那么你也必须仅在
saveat
SavingCallback
使用最后一个时间步,而不是(仅)
solve
命令。目前,您向
SavingCallback
提供了保存在
tt:dts:tf

的说明
© www.soinside.com 2019 - 2024. All rights reserved.