Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 3.94 KB | None | 0 0
  1. using Revise
  2.     using LinearAlgebra, Plots, SparseArrays, Setfield, Parameters
  3.  
  4. f1(u, v) = u^2 * v
  5. norminf = x -> norm(x, Inf)
  6.  
  7. function plotsol(x; kwargs...)
  8.     N = div(length(x), 2)
  9.     plot!(x[1:N], label="u"; kwargs...)
  10.     plot!(x[N+1:2N], label="v"; kwargs...)
  11. end
  12.  
  13. function Fbru!(f, x, p)
  14.     @unpack α, β, D1, D2, l = p
  15.     n = div(length(x), 2)
  16.     h = 1.0 / (n+0); h2 = h*h
  17.     c1 = D1 / l^2 / h2
  18.     c2 = D2 / l^2 / h2
  19.  
  20.     u = @view x[1:n]
  21.     v = @view x[n+1:2n]
  22.  
  23.     # Dirichlet boundary conditions
  24.     f[1]   = c1 * (α     - 2u[1] + u[2] ) + α - (β + 1) * u[1] + f1(u[1], v[1])
  25.     f[end] = c2 * (v[n-1] - 2v[n] + β / α)             + β * u[n] - f1(u[n], v[n])
  26.  
  27.     f[n]   = c1 * (u[n-1] - 2u[n] +  α   ) + α - (β + 1) * u[n] + f1(u[n], v[n])
  28.     f[n+1] = c2 * (β / α  - 2v[1] + v[2])          + β * u[1] - f1(u[1], v[1])
  29.  
  30.     for i=2:n-1
  31.           f[i] = c1 * (u[i-1] - 2u[i] + u[i+1]) + α - (β + 1) * u[i] + f1(u[i], v[i])
  32.         f[n+i] = c2 * (v[i-1] - 2v[i] + v[i+1])           + β * u[i] - f1(u[i], v[i])
  33.     end
  34.     return f
  35. end
  36.  
  37. function Fbru(x, p)
  38.     f = similar(x)
  39.     Fbru!(f, x, p)
  40. end
  41.  
  42. function Jbru_sp(x, p)
  43.     @unpack α, β, D1, D2, l = p
  44.     # compute the Jacobian using a sparse representation
  45.     n = div(length(x), 2)
  46.     h = 1.0 / (n+0); h2 = h*h
  47.  
  48.     c1 = D1 / p.l^2 / h2
  49.     c2 = D2 / p.l^2 / h2
  50.  
  51.     u = @view x[1:n]
  52.     v = @view x[n+1:2n]
  53.  
  54.     diag   = zeros(eltype(x), 2n)
  55.     diagp1 = zeros(eltype(x), 2n-1)
  56.     diagm1 = zeros(eltype(x), 2n-1)
  57.  
  58.     diagpn = zeros(eltype(x), n)
  59.     diagmn = zeros(eltype(x), n)
  60.  
  61.     @. diagmn = β - 2 * u * v
  62.     @. diagm1[1:n-1] = c1
  63.     @. diagm1[n+1:end] = c2
  64.  
  65.     @. diag[1:n]    = -2c1 - (β + 1) + 2 * u * v
  66.     @. diag[n+1:2n] = -2c2 - u * u
  67.  
  68.     @. diagp1[1:n-1]   = c1
  69.     @. diagp1[n+1:end] = c2
  70.  
  71.     @. diagpn = u * u
  72.     J = spdiagm(0 => diag, 1 => diagp1, -1 => diagm1, n => diagpn, -n => diagmn)
  73.     return J
  74. end
  75.  
  76. function finalise_solution(z, tau, step, contResult)
  77.     n = div(length(z.u), 2)
  78.     printstyled(color=:red, "--> Solution constant = ", norm(diff(z.u[1:n])), " - ", norm(diff(z.u[n+1:2n])), "\n")
  79.     return true
  80. end
  81.  
  82. n = 100
  83. ####################################################################################################
  84. # test for the Jacobian expression
  85. # using ForwardDiff
  86. # sol0 = rand(2n)
  87. # J0 = ForwardDiff.jacobian(x-> Fbru(x, par_bru), sol0) |> sparse
  88. # J1 = Jbru_sp(sol0, par_bru)
  89. # J0 - J1
  90. ####################################################################################################
  91. # different parameters to define the Brusselator model and guess for the stationary solution
  92. par_bru = (α = 2., β = 5.45, D1 = 0.008, D2 = 0.004, l = 0.3)
  93.     sol0 = vcat(par_bru.α * ones(n), par_bru.β/par_bru.α * ones(n))
  94.  
  95.  
  96.  
  97. using DifferentialEquations, DiffEqOperators, Sundials, ForwardDiff
  98.  
  99. function plotPeriodic(x)
  100.     n = div(size(x,1),2)
  101.     plot(heatmap(x[1:n,:]', ylabel="Time", color=:viridis),
  102.             heatmap(x[n+1:end,:]', color=:viridis))
  103. end
  104.  
  105. FOde(f, x, p, t) = Fbru!(f, x, p)
  106. Jbru(x, dx, p) = ForwardDiff.derivative(t -> Fbru(x .+ t .* dx, p), 0.)
  107. JacOde(J, x, p, t) = copyto!(J, Jbru_sp(x, p)) 
  108.  
  109. u0 = sol0 .+ 0.01 .* rand(2n)
  110. par_hopf = (@set par_bru.l = 0.51792 + 0.01)
  111.  
  112. jac_prototype = Jbru_sp(ones(sol0|> length), @set par_bru.β = 0)
  113.     jac_prototype.nzval .= ones(length(jac_prototype.nzval))
  114.  
  115. ff = ODEFunction(FOde, jac_prototype = JacVecOperator{Float64}(FOde, u0, par_hopf))
  116. prob = ODEProblem(ff, u0, (0., 5400.), par_hopf)
  117. probsundials = ODEProblem(FOde, u0, (0., 5200.), par_hopf)
  118.  
  119. M = 3
  120.     sol = @time solve(probsundials, CVODE_BDF(linear_solver=:GMRES), saveat = LinRange(820-Thopf, 820, M+1))
  121.  
  122.  
  123. function sectionP(x, po::AbstractMatrix, p)
  124.     res = 1.0
  125.     N, M = size(po)
  126.  
  127.     for ii = 1:size(x,2)
  128.         res *= dot(x .- po[:, ii], Fbru(po[:, ii], p))
  129.     end
  130.     @show p res
  131.     res
  132. end
  133.  
  134. M = 1
  135. affect!(integrator) = terminate!(integrator)
  136. pSection(u, t, integrator) = (sectionP(u, Array(sol[:,1:M]), par_hopf)) * (integrator.iter > 1)
  137. cb = ContinuousCallback(pSection, affect!)
  138. solve(probsundials, Rodas4(), save_everystep = false, callback = cb)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement