The Brusselator PDE¶
The Brusselator is a theoretical model for autocatalytic reactions. In this example, we solve a 2D reaction-diffusion system on the unit square with no-flux boundary conditions.
using ComponentArrays: ComponentArray
using SimpleUnPack
using OrdinaryDiffEqModel parameters and initial conditions
function build_u0_ps(; x_min=0.0, x_max=1.0, y_min=0.0, y_max=1.0, α=10.0, N=26::Int)
u0 = ComponentArray(u=zeros(N, N), v=zeros(N, N))
xx = range(x_min, x_max, length=N)
yy = range(y_min, y_max, length=N)
dx = step(xx)
dy = step(yy)
for I in CartesianIndices((N, N))
x = xx[I[1]]
y = yy[I[2]]
u0.u[I] = 22 * (y * (1 - y))
u0.v[I] = 27 * (x * (1 - x))
end
ps = (; xx=xx, yy=yy, Dx=α/dx^2, Dy=α/dy^2, N=N)
return u0, ps
endbuild_u0_ps (generic function with 1 method)A discretized PDE problem is a coupled ODE problem under the hood.
function model!(ds, s, p, t)
SimpleUnPack.@unpack xx, yy, Dx, Dy, N = p
SimpleUnPack.@unpack u, v = s
brusselator_f(x, y, t) = (((x - 0.3)^2 + (y - 0.6)^2) <= 0.1^2) * (t >= 1.1) * 5
# Interating all grid points
@inbounds for I in CartesianIndices((N, N))
i, j = Tuple(I)
x = xx[I[1]]
y = yy[I[2]]
uterm = 1.0 + v[i, j] * u[i, j]^2 - 4.4 * u[i, j] + brusselator_f(x, y, t)
vterm = 3.4 * u[i, j] - v[i, j] * u[i, j]^2
# No flux boundary conditions
i_prev = clamp(i - 1, 1, N)
i_next = clamp(i + 1, 1, N)
j_prev = clamp(j - 1, 1, N)
j_next = clamp(j + 1, 1, N)
unabla = Dx * (u[i, j_prev] - 2u[i, j] + u[i, j_next]) + Dy * (u[i_prev, j] - 2u[i, j] + u[i_next, j])
vnabla = Dx * (v[i, j_prev] - 2v[i, j] + v[i, j_next]) + Dy * (v[i_prev, j] - 2v[i, j] + v[i_next, j])
ds.u[i, j] = unabla + uterm
ds.v[i, j] = vnabla + vterm
end
return nothing
endmodel! (generic function with 1 method)u0, ps = build_u0_ps(;N=26)
tspan = (0, 11.5)
prob = ODEProblem(model!, u0, tspan, ps)
@time sol = solve(prob, FBDF(), saveat=0.1) 16.956261 seconds (25.59 M allocations: 1.476 GiB, 3.96% gc time, 60.18% compilation time)
retcode: Success
Interpolation: 1st order linear
t: 116-element Vector{Float64}:
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
⋮
10.7
10.8
10.9
11.0
11.1
11.2
11.3
11.4
11.5
u: 116-element Vector{ComponentArrays.ComponentVector{Float64, Vector{Float64}, Tuple{ComponentArrays.Axis{(u = ViewAxis(1:676, ShapedAxis((26, 26))), v = ViewAxis(677:1352, ShapedAxis((26, 26))))}}}}:
ComponentVector{Float64}(u = [0.0 0.8447999999999999 … 0.8448000000000007 0.0; 0.0 0.8447999999999999 … 0.8448000000000007 0.0; … ; 0.0 0.8447999999999999 … 0.8448000000000007 0.0; 0.0 0.8447999999999999 … 0.8448000000000007 0.0], v = [0.0 0.0 … 0.0 0.0; 1.0368 1.0368 … 1.0368 1.0368; … ; 1.0368000000000008 1.0368000000000008 … 1.0368000000000008 1.0368000000000008; 0.0 0.0 … 0.0 0.0])
ComponentVector{Float64}(u = [6.69096653528674 6.690966552529425 … 6.690966552524531 6.690966535281775; 6.690966527005339 6.690966541513271 … 6.690966541508378 6.6909665270003735; … ; 6.690966527001637 6.69096654150957 … 6.690966541504676 6.690966526996672; 6.690966535282983 6.690966552525671 … 6.690966552520777 6.69096653527802], v = [0.6972533574560303 0.6972533400145913 … 0.6972533400161111 0.6972533574575731; 0.6972533653234309 0.6972533506211764 … 0.6972533506226962 0.6972533653249736; … ; 0.6972533653237378 0.6972533506214829 … 0.6972533506230026 0.6972533653252803; 0.6972533574563416 0.6972533400149021 … 0.6972533400164217 0.6972533574578843])
ComponentVector{Float64}(u = [6.301782389642485 6.301782384800974 … 6.301782384800978 6.30178238964249; 6.3017823536093225 6.301782346660492 … 6.301782346660495 6.301782353609327; … ; 6.301782353609325 6.301782346660494 … 6.301782346660498 6.3017823536093305; 6.301782389642489 6.301782384800979 … 6.3017823848009815 6.301782389642493], v = [0.5313511771657147 0.5313511820472901 … 0.5313511820472908 0.5313511771657151; 0.5313512133559963 0.53135122034644 … 0.5313512203464407 0.5313512133559969; … ; 0.531351213355997 0.5313512203464407 … 0.5313512203464413 0.5313512133559976; 0.5313511771657153 0.5313511820472908 … 0.5313511820472914 0.5313511771657159])
ComponentVector{Float64}(u = [5.754724881789618 5.754724881915459 … 5.754724881915459 5.754724881789618; 5.754724887490693 5.754724888005622 … 5.754724888005622 5.754724887490693; … ; 5.754724887490693 5.754724888005622 … 5.754724888005623 5.754724887490693; 5.754724881789618 5.754724881915459 … 5.754724881915459 5.754724881789618], v = [0.5759005587297428 0.5759005586009586 … 0.5759005586009586 0.5759005587297428; 0.57590055300696 0.5759005524887555 … 0.5759005524887554 0.57590055300696; … ; 0.57590055300696 0.5759005524887554 … 0.5759005524887554 0.57590055300696; 0.5759005587297428 0.5759005586009586 … 0.5759005586009586 0.5759005587297428])
ComponentVector{Float64}(u = [5.252844305348785 5.252844304620054 … 5.252844304620054 5.252844305348784; 5.252844304036483 5.252844303304624 … 5.252844303304624 5.252844304036483; … ; 5.252844304036483 5.252844303304624 … 5.252844303304624 5.252844304036483; 5.252844305348784 5.252844304620054 … 5.252844304620054 5.252844305348784], v = [0.6277884270943329 0.6277884278269426 … 0.6277884278269423 0.6277884270943329; 0.6277884284143053 0.6277884291500765 … 0.6277884291500765 0.6277884284143053; … ; 0.6277884284143053 0.6277884291500765 … 0.6277884291500765 0.6277884284143053; 0.6277884270943329 0.6277884278269423 … 0.6277884278269426 0.6277884270943329])
ComponentVector{Float64}(u = [4.794820652796592 4.794820652718602 … 4.794820652718602 4.794820652796593; 4.7948206522115715 4.794820652127291 … 4.794820652127291 4.7948206522115715; … ; 4.7948206522115715 4.794820652127291 … 4.794820652127291 4.7948206522115715; 4.794820652796593 4.794820652718602 … 4.794820652718602 4.794820652796593], v = [0.683829299963002 0.6838293000432372 … 0.6838293000432373 0.683829299963002; 0.6838293005552177 0.6838293006417587 … 0.6838293006417587 0.6838293005552177; … ; 0.6838293005552177 0.6838293006417587 … 0.6838293006417587 0.6838293005552177; 0.683829299963002 0.6838293000432373 … 0.6838293000432372 0.683829299963002])
ComponentVector{Float64}(u = [4.376142599515105 4.376142599534686 … 4.376142599534686 4.376142599515105; 4.376142599554547 4.376142599574152 … 4.376142599574152 4.376142599554547; … ; 4.376142599554547 4.376142599574152 … 4.376142599574152 4.376142599554547; 4.376142599515105 4.376142599534686 … 4.376142599534686 4.376142599515105], v = [0.7442160138508933 0.7442160138311635 … 0.7442160138311635 0.7442160138508933; 0.7442160138110899 0.7442160137913352 … 0.7442160137913352 0.7442160138110899; … ; 0.7442160138110899 0.7442160137913352 … 0.7442160137913352 0.7442160138110899; 0.7442160138508933 0.7442160138311635 … 0.7442160138311635 0.7442160138508933])
ComponentVector{Float64}(u = [3.9927328901747416 3.992732890169732 … 3.992732890169732 3.9927328901747416; 3.992732890165716 3.992732890160706 … 3.992732890160706 3.992732890165716; … ; 3.992732890165716 3.992732890160706 … 3.992732890160706 3.992732890165716; 3.9927328901747416 3.992732890169732 … 3.992732890169732 3.9927328901747416], v = [0.8092271899207291 0.8092271899257504 … 0.8092271899257504 0.8092271899207291; 0.8092271899297787 0.809227189934801 … 0.809227189934801 0.8092271899297787; … ; 0.8092271899297787 0.809227189934801 … 0.809227189934801 0.8092271899297787; 0.8092271899207291 0.8092271899257504 … 0.8092271899257504 0.8092271899207291])
ComponentVector{Float64}(u = [3.641195766503151 3.6411957665054873 … 3.6411957665054873 3.641195766503151; 3.641195766506122 3.6411957665084493 … 3.6411957665084493 3.641195766506122; … ; 3.641195766506122 3.6411957665084493 … 3.6411957665084493 3.641195766506122; 3.641195766503151 3.6411957665054873 … 3.6411957665054873 3.641195766503151], v = [0.8791293083331657 0.879129308330821 … 0.879129308330821 0.8791293083331657; 0.8791293083301832 0.8791293083278482 … 0.8791293083278482 0.8791293083301832; … ; 0.8791293083301832 0.8791293083278482 … 0.8791293083278482 0.8791293083301832; 0.8791293083331657 0.879129308330821 … 0.879129308330821 0.8791293083331657])
ComponentVector{Float64}(u = [3.318461186897513 3.318461186893368 … 3.318461186893368 3.318461186897513; 3.318461186888884 3.318461186884744 … 3.318461186884744 3.318461186888884; … ; 3.318461186888884 3.318461186884744 … 3.318461186884744 3.318461186888884; 3.318461186897513 3.318461186893368 … 3.318461186893368 3.318461186897513], v = [0.9541185407049886 0.9541185407091418 … 0.9541185407091418 0.9541185407049886; 0.954118540713636 0.9541185407177871 … 0.9541185407177871 0.9541185407136362; … ; 0.954118540713636 0.9541185407177871 … 0.9541185407177871 0.954118540713636; 0.9541185407049886 0.9541185407091418 … 0.9541185407091418 0.9541185407049886])
⋮
ComponentVector{Float64}(u = [0.40458659783319895 0.4046184632861027 … 0.4064159836925868 0.40638815413465545; 0.40457716348147477 0.40460923558154016 … 0.40641239482118674 0.4063830666904621; … ; 0.4027473056431877 0.4027549327320313 … 0.4034137310116993 0.4034149873322929; 0.40273264017127675 0.4027400801916543 … 0.40338995371389824 0.4033913595782937], v = [4.107509763943594 4.107509783274427 … 4.10751143557818 4.107511437678164; 4.107509746320316 4.107509765662652 … 4.107511416734608 4.1075114186925825; … ; 4.107507094379255 4.107507104355325 … 4.107508208563356 4.1075082146727935; 4.107507073535586 4.10750708342604 … 4.107508182678202 4.107508188820574])
ComponentVector{Float64}(u = [0.4082104721929923 0.40824235981199236 … 0.41004172323475924 0.41001389355807455; 0.40820102039440476 0.4082331146647396 … 0.41003811463143003 0.41000878616824094; … ; 0.4063685567373823 0.40637619347368953 … 0.4070360473232633 0.4070373092830191; 0.4063538711477651 0.40636132071349457 … 0.40701224346326365 0.4070136550029048], v = [4.1772881356694 4.17728813266637 … 4.177287923232497 4.177287925350724; 4.177288135725217 4.17728813272975 … 4.1772879243807015 4.177287926570955; … ; 4.177288121851867 4.177288122068114 … 4.177288156685949 4.1772881570619775; 4.177288121368603 4.177288121601795 … 4.177288157643139 4.177288158016061])
ComponentVector{Float64}(u = [0.41263215151264787 0.412664063037067 … 0.4144654153592041 0.41443758558317767; 0.41262268086939013 0.41265479904959146 … 0.4144617854454369 0.41443245665281386; … ; 0.4107874032047464 0.4107950503577528 … 0.41145604439662475 0.41145731245279105; 0.4107726958911814 0.4107801557635721 … 0.4114322118662272 0.411433629541116], v = [4.245869973403156 4.2458699463135865 … 4.245867727759423 4.245867729868317; 4.245869992554614 4.245869965468408 … 4.245867750498816 4.245867752910175; … ; 4.245872827537521 4.245872817215655 … 4.24587169649133 4.245871690669057; 4.2458728490404605 4.24587283884606 … 4.2458717264215435 4.245871720557375])
ComponentVector{Float64}(u = [0.41779869541006354 0.4178306325751821 … 0.4196341198932433 0.41960629004885946; 0.41778920451591317 0.4178213483415067 … 0.41963046708144097 0.4196011379741687; … ; 0.41595090367997284 0.4159585620217002 … 0.41662078137625147 0.4166220559910421; 0.41593617302943436 0.4159436439726389 … 0.41659691806300175 0.4165983423380639], v = [4.313196564787747 4.313196511862867 … 4.313192136572703 4.313192138632951; 4.313196604460119 4.313196551534179 … 4.3131921825121 4.313192185121482; … ; 4.313202500104276 4.313202478463083 … 4.313200116118202 4.313200103627623; 4.313202545226301 4.313202523831003 … 4.313200177156674 4.313200164582707])
ComponentVector{Float64}(u = [0.42367979275773904 0.423711757112097 … 0.4255175098760886 0.4254896799920783; 0.4236702803555817 0.42370245137533313 … 0.42551383274779414 0.4254845033401397; … ; 0.4218287694130589 0.42183643963335477 … 0.4224999604193219 0.422501242006536; 0.42181401398415386 0.42182149668100477 … 0.4224760644367722 0.42247749572822896], v = [4.379266763931133 4.379266683610924 … 4.37926001984804 4.379260021823943; 4.379266825397596 4.379266745071685 … 4.379260090423812 4.379260093209999; … ; 4.379275970866991 4.379275937208862 … 4.379272256156965 4.379272236577738; 4.379276041066267 4.379276007779498 … 4.379272350209431 4.379272330502896])
ComponentVector{Float64}(u = [0.43028705478542323 0.430319048284152 … 0.43212722879881604 0.43209939886173077; 0.43027751933931835 0.43030971950875496 … 0.4321235256184097 0.4320941958780775; … ; 0.4284325686779616 0.4284402516277172 … 0.4291051668392112 0.42910645589460417; 0.4284177866968904 0.42842528198925495 … 0.42908123584525315 0.4290826746520652], v = [4.443981202396884 4.443981092711707 … 4.443971976560039 4.443971978456474; 4.443981287213276 4.443981177517386 … 4.443972073530113 4.443972076516861; … ; 4.4439939148862875 4.443993868350687 … 4.4439887743971855 4.443988747225511; 4.44399401195744 4.443993965927738 … 4.443988903829861 4.443988876483762])
ComponentVector{Float64}(u = [0.4376773351044231 0.437709359670681 … 0.43952013110002214 0.43949230117159893; 0.43766777503075743 0.4377000062732229 … 0.43951640007899323 0.43948707005015075; … ; 0.43581914970888885 0.43582684625348034 … 0.4364932517157809 0.4364945487642353; 0.43580433936530527 0.4358118481099181 … 0.43646928334876606 0.4364707301987283], v = [4.507213468182314 4.507213327193823 … 4.50720159377045 4.507201595516155; 4.5072135779538955 4.507213436949514 … 4.507201718947415 4.5072017220810565; … ; 4.5072299257709085 4.507229865482033 … 4.5072232614921734 4.507223226194288; 4.507230051546825 4.507229991907062 … 4.507223428692502 4.507223393170168])
ComponentVector{Float64}(u = [0.445917439576168 0.4459494973368722 … 0.44776303811367885 0.44773520821741813; 0.44590785316349113 0.44594011760625973 … 0.4477592773209824 0.44772994700704744; … ; 0.4440552983151852 0.4440630093962197 … 0.44473100875104843 0.4447323143531885; 0.44404045764294464 0.4440479807717285 … 0.44470700043201644 0.44470845588913105], v = [4.568824085749234 4.568823911314495 … 4.568809380391507 4.56880938195325; 4.568824222209868 4.568824047753726 … 4.568809535731405 4.568809538998824; … ; 4.568844548147012 4.568844473152422 … 4.56883625412968 4.568836210135828; 4.568844704617237 4.568844630424698 … 4.568836461703531 4.568836417431828])
ComponentVector{Float64}(u = [0.45510128134205574 0.45513337473650883 … 0.4569498898424267 0.45692206001457386; 0.4550916666223787 0.45512396670510297 … 0.4569460970550789 0.45691676646947205; … ; 0.45323488932130834 0.4532426160206029 … 0.45391232838717915 0.45391364318800426; 0.4532200160607801 0.45322755464446074 … 0.4538882771530464 0.45388974186614306], v = [4.62861342386824 4.62861321352949 … 4.628595678056942 4.628595679387271; 4.628613589011688 4.628613378645696 … 4.628595865811545 4.628595869188145; … ; 4.628638189572399 4.628638098777822 … 4.6286281440460675 4.628628090700756; 4.628638379023475 4.628638289195028 … 4.62862839498751 4.628628341307126])This notebook was generated using Literate.jl.