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) 22.869231 seconds (25.80 M allocations: 1.454 GiB, 1.70% gc time, 41.94% 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.690974984007653 6.690975001822107 … 6.6909750018117204 6.690974983997116; 6.690974975116299 6.690974990390786 … 6.690974990380409 6.690974975105758; … ; 6.690974975113438 6.690974990387927 … 6.690974990377549 6.6909749751028995; 6.690974984004754 6.690975001819204 … 6.6909750018088205 6.6909749839942165], v = [0.6972489073156851 0.6972488891401697 … 0.6972488891434477 0.6972489073190079; 0.6972489155831907 0.6972488999523364 … 0.6972488999556022 0.6972489155865178; … ; 0.6972489155834277 0.6972488999525726 … 0.6972488999558377 0.6972489155867551; 0.6972489073159249 0.6972488891404098 … 0.6972488891436883 0.6972489073192479])
ComponentVector{Float64}(u = [6.3017864066105655 6.301786401752524 … 6.301786401752529 6.301786406610573; 6.301786370385783 6.301786363408424 … 6.301786363408436 6.30178637038579; … ; 6.301786370385786 6.301786363408426 … 6.3017863634084375 6.301786370385792; 6.301786406610568 6.301786401752526 … 6.301786401752532 6.301786406610577], v = [0.5313506273837374 0.5313506322813808 … 0.5313506322813811 0.5313506273837391; 0.5313506637655242 0.5313506707840377 … 0.5313506707840416 0.5313506637655243; … ; 0.5313506637655242 0.5313506707840394 … 0.5313506707840415 0.531350663765525; 0.5313506273837382 0.531350632281381 … 0.5313506322813818 0.5313506273837396])
ComponentVector{Float64}(u = [5.754728677829969 5.754728677949021 … 5.754728677949021 5.754728677829968; 5.754728683501431 5.754728684007517 … 5.754728684007516 5.7547286835014315; … ; 5.7547286835014315 5.754728684007512 … 5.754728684007516 5.7547286835014315; 5.754728677829966 5.754728677949023 … 5.754728677949021 5.754728677829968], v = [0.5758998312352215 0.5758998311133672 … 0.5758998311133672 0.5758998312352216; 0.5758998255423224 0.5758998250331073 … 0.5758998250331078 0.5758998255423223; … ; 0.5758998255423221 0.575899825033108 … 0.5758998250331073 0.5758998255423224; 0.5758998312352216 0.5758998311133671 … 0.5758998311133673 0.5758998312352215])
ComponentVector{Float64}(u = [5.252847377392548 5.252847376660399 … 5.2528473766604 5.25284737739255; 5.252847376076641 5.2528473753413145 … 5.252847375341316 5.252847376076642; … ; 5.25284737607664 5.25284737534132 … 5.25284737534132 5.252847376076639; 5.252847377392549 5.252847376660399 … 5.252847376660397 5.252847377392549], v = [0.6277880907790726 0.6277880915150558 … 0.6277880915150552 0.6277880907790729; 0.6277880921026566 0.6277880928418448 … 0.6277880928418464 0.6277880921026565; … ; 0.6277880921026573 0.6277880928418437 … 0.6277880928418461 0.6277880921026565; 0.6277880907790726 0.6277880915150561 … 0.6277880915150552 0.6277880907790728])
ComponentVector{Float64}(u = [4.794823646740092 4.794823646660868 … 4.794823646660854 4.794823646740079; 4.794823646138433 4.794823646052611 … 4.794823646052602 4.794823646138415; … ; 4.79482364613842 4.794823646052594 … 4.794823646052609 4.794823646138429; 4.794823646740078 4.794823646660856 … 4.794823646660866 4.794823646740089], v = [0.683828816606854 0.6838288166883293 … 0.6838288166883353 0.68382881660686; 0.6838288172157881 0.6838288173038748 … 0.6838288173038803 0.6838288172157944; … ; 0.6838288172157877 0.6838288173038753 … 0.6838288173038791 0.6838288172157923; 0.6838288166068542 0.6838288166883291 … 0.6838288166883334 0.6838288166068587])
ComponentVector{Float64}(u = [4.376147537542502 4.376147537561973 … 4.376147537561945 4.376147537542476; 4.37614753758229 4.376147537601783 … 4.376147537601757 4.376147537582264; … ; 4.376147537582267 4.376147537601758 … 4.376147537601778 4.376147537582284; 4.3761475375424785 4.37614753756195 … 4.376147537561968 4.376147537542496], v = [0.7442155456344994 0.7442155456148262 … 0.7442155456148402 0.7442155456345139; 0.7442155455942755 0.744215545574584 … 0.7442155455745982 0.7442155455942898; … ; 0.7442155455942754 0.7442155455745847 … 0.7442155455745955 0.7442155455942855; 0.7442155456344998 0.7442155456148258 … 0.7442155456148358 0.7442155456345103])
ComponentVector{Float64}(u = [3.992737706761862 3.9927377067568375 … 3.9927377067568193 3.9927377067618264; 3.9927377067526892 3.992737706747647 … 3.9927377067476204 3.9927377067526497; … ; 3.9927377067527345 3.992737706747685 … 3.992737706747621 3.9927377067526626; 3.992737706761916 3.9927377067568877 … 3.992737706756812 3.9927377067618353], v = [0.8092263137515917 0.8092263137566065 … 0.8092263137566097 0.809226313751596; 0.809226313760795 0.8092263137658333 … 0.8092263137658373 0.8092263137607989; … ; 0.8092263137607878 0.8092263137658271 … 0.8092263137658312 0.8092263137607926; 0.8092263137515826 0.8092263137565969 … 0.8092263137566039 0.8092263137515877])
ComponentVector{Float64}(u = [3.6411995339637357 3.6411995339659864 … 3.641199533966431 3.6411995339643615; 3.6411995339665686 3.6411995339688543 … 3.641199533969334 3.641199533967214; … ; 3.6411995339662977 3.6411995339686287 … 3.6411995339691146 3.6411995339668475; 3.641199533963326 3.641199533965631 … 3.641199533966285 3.6411995339640435], v = [0.8791282259946718 0.8791282259924353 … 0.8791282259923862 0.8791282259946147; 0.8791282259917431 0.8791282259894676 … 0.8791282259894205 0.8791282259916933; … ; 0.87912822599181 0.8791282259895334 … 0.8791282259894957 0.8791282259917834; 0.8791282259947695 0.8791282259925329 … 0.87912822599247 0.8791282259947215])
ComponentVector{Float64}(u = [3.3184626516374083 3.318462651633492 … 3.318462651634393 3.318462651638304; 3.3184626516290088 3.318462651625038 … 3.31846265162587 3.3184626516298255; … ; 3.318462651629592 3.3184626516255853 … 3.318462651625479 3.3184626516295146; 3.3184626516381077 3.3184626516341273 … 3.3184626516338978 3.3184626516378706], v = [0.9541176955360849 0.9541176955400734 … 0.9541176955398962 0.9541176955359175; 0.9541176955446261 0.9541176955486651 … 0.9541176955484849 0.9541176955444545; … ; 0.9541176955446289 0.9541176955486556 … 0.9541176955485343 0.9541176955444928; 0.95411769553608 0.9541176955400528 … 0.9541176955399455 0.9541176955359595])
⋮
ComponentVector{Float64}(u = [0.40457146680306544 0.40460333219358563 … 0.406400847343715 0.4063730177847979; 0.40456203250197487 0.4045941045396321 … 0.4063972585293293 0.40636793039818225; … ; 0.4027321822026777 0.40273980926352704 … 0.4033986044714187 0.4033998607754786; 0.4027175167889389 0.40272495678161946 … 0.4033748272496847 0.4033762330974579], v = [4.107398046757783 4.107398066151743 … 4.10739972378771 4.107399725889027; 4.107398029083284 4.107398048488766 … 4.107399704886232 4.10739970684498; … ; 4.107395369527173 4.107395379531138 … 4.107396486835604 4.107396492962008; 4.10739534862484 4.107395358542886 … 4.107396460873422 4.107396467032845])
ComponentVector{Float64}(u = [0.40819345475596636 0.40822534231813 … 0.41002470097426563 0.40999687129704615; 0.40818400300305624 0.4082160972165078 … 0.4100210924224388 0.40999176395925657; … ; 0.4063515461452493 0.4063591828564687 … 0.40701903394154665 0.407020295886357; 0.4063368606081175 0.4063443101490072 … 0.40699523015038963 0.40699664167500804], v = [4.177179728157024 4.177179725211098 … 4.177179520593758 4.177179522712958; 4.177179728166456 4.177179725228137 … 4.177179521689695 4.1771795238803735; … ; 4.177179707401231 4.177179707642876 … 4.177179745065845 4.177179745457144; 4.177179706864807 4.17717970712315 … 4.177179745953482 4.177179746341754])
ComponentVector{Float64}(u = [0.4126134234214086 0.41264533489158295 … 0.41444668269648116 0.4144188529205197; 0.4126039528211121 0.4126360709470098 … 0.41444305283120675 0.4144137240391911; … ; 0.410768681556711 0.41077632868622277 … 0.4114373201294462 0.4114385881715662; 0.4107539742925737 0.41076143414169025 … 0.41141348766414454 0.41141490532491315], v = [4.245764961632635 4.2457649345972195 … 4.2457627205911255 4.245762722700474; 4.245764980740338 4.245764953708346 … 4.245762743281334 4.245762745692604; … ; 4.245767809218258 4.245767798920519 … 4.245766680843884 4.245766675035869; 4.2457678306709505 4.245767820500463 … 4.245766710708469 4.24576670485863])
ComponentVector{Float64}(u = [0.41778001989326224 0.417811957005558 … 0.419615439960933 0.41958761011726076; 0.41777052904006057 0.4178026728127795 … 0.4196117871955581 0.4195824580895457; … ; 0.4159322343115042 0.4159398926309425 … 0.41660210952198556 0.41660338412344566; 0.4159175037081041 0.41592497462924083 … 0.41657824627137446 0.41657967053301415], v = [4.313093070047339 4.313093017174911 … 4.313088646247007 4.313088648306905; 4.3130931096779435 4.313093056804511 … 4.313088692139537 4.313088694748013; … ; 4.313098999098829 4.313098977480967 … 4.31309661766722 4.313096605189999; 4.313099044172726 4.31309902280055 … 4.313096678642762 4.313096666082239])
ComponentVector{Float64}(u = [0.42366147568047013 0.423693439973036 … 0.4254991876618353 0.4254713577793714; 0.42365196332569527 0.4236841342836588 … 0.42549551058715895 0.42546618118165447; … ; 0.42181045950102086 0.42181812969486815 … 0.42248164760750845 0.4224829291797676; 0.4217957041271514 0.42180318679785483 … 0.4224577516980819 0.4224591829745005], v = [4.379162649876656 4.379162569618697 … 4.3791559109767055 4.379155912951243; 4.379162711295293 4.37916263103163 … 4.379155981498304 4.379155984282524; … ; 4.379171849586914 4.379171815955305 … 4.379168137800202 4.379168118236197; 4.379171919730734 4.379171886470183 … 4.379168231778921 4.379168212087692])
ComponentVector{Float64}(u = [0.4302687342161307 0.4303007276491574 … 0.43210890267552854 0.4320810727382083; 0.4302591988222805 0.430291398925993 … 0.43210519955421894 0.43207586981428076; … ; 0.42841425594866006 0.42842193886964447 … 0.4290868509225751 0.42908813996090395; 0.42839947402769346 0.4284069692915815 … 0.4290629200077713 0.429064358797403], v = [4.443879381567849 4.4438792719488145 … 4.443870161340331 4.443870163237355; 4.443879466331223 4.4438793567014985 … 4.44387025825049 4.443870261237194; … ; 4.443892086109413 4.443892039603064 … 4.443886948856159 4.4438869217017825; 4.44389218311963 4.443892137118884 … 4.443887078208821 4.443887050880136])
ComponentVector{Float64}(u = [0.43765789367839225 0.43768991817850506 … 0.43950068408700316 0.4394728541584262; 0.4376483336571504 0.43768056483346046 … 0.43949695312533116 0.4394676230969697; … ; 0.4357997161577908 0.43580741267356343 … 0.4364738149652206 0.4364751119965426; 0.4357849058746045 0.4357924145907002 … 0.4364498466777967 0.43645129351051254], v = [4.507114600331926 4.507114459409991 … 4.507102731548424 4.507102733294451; 4.507114710050336 4.507114569112523 … 4.507102856665383 4.507102859798712; … ; 4.507131049934998 4.507130989675551 … 4.507124388910947 4.507124353630395; 4.507131175649639 4.5071311160390035 … 4.507124556030931 4.507124520526045])
ComponentVector{Float64}(u = [0.4458967583762584 0.4459288160664805 … 0.44774235097135223 0.4477145210752175; 0.4458871720194553 0.4459194363917163 … 0.4477385902416858 0.4477092599285354; … ; 0.44403462550651346 0.4440423365565449 … 0.4447103325302679 0.4447116381144159; 0.44401978489852356 0.44402730799663814 … 0.44468632429597227 0.4446877797350197], v = [4.568728196779482 4.56872802241584 … 4.568713497435188 4.568713498997212; 4.568728333183481 4.568728158798461 … 4.5687136527111205 4.568713655978158; … ; 4.56874865068555 4.568748575722103 … 4.568740360120637 4.56874031614522; 4.568748807090824 4.568748732929091 … 4.568740567608784 4.568740523355589])
ComponentVector{Float64}(u = [0.45507853196523124 0.4551106252836611 … 0.4569271340357409 0.4568993042075156; 0.4550689173060348 0.4551012173127321 … 0.4569233413167617 0.4568940107314987; … ; 0.4532121490240242 0.45321987568995487 … 0.4538895843990997 0.4538908991803069; 0.4531972758330917 0.453204814383764 … 0.45386553325665285 0.45386699795002455], v = [4.628522120209299 4.628521909947156 … 4.628504380887174 4.628504382218136; 4.628522285291394 4.628522075002015 … 4.628504568572553 4.628504571949068; … ; 4.628546876711278 4.62854678595052 … 4.628536834933533 4.628536781608217; 4.628547066091833 4.628546976296851 … 4.628537085782336 4.6285370321220505])This notebook was generated using Literate.jl.