Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Modeling the Brusselator PDE:

ut=1+u2v4.4u+α(2ux2+2uy2)+f(x,y,t)vt=3.4uu2v+α(2ux2+2uy2)\begin{align} \frac{\partial u}{\partial t} &= 1 + u^2v - 4.4u + \alpha (\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2}) + f(x, y, t) \\ \frac{\partial v}{\partial t} &= 3.4u - u^2 v + \alpha (\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2}) \end{align}
using ComponentArrays: ComponentArray
using SimpleUnPack
using OrdinaryDiffEq
using Plots

Model 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
end
build_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
end
model! (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)
 37.116992 seconds (26.64 M allocations: 1.484 GiB, 2.87% gc time, 27.04% 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.690972491999713 6.6909725096572075 … 6.69097250965787 6.690972492000381; 6.690972483258849 6.690972498323129 … 6.690972498323783 6.690972483259521; … ; 6.690972483254976 6.6909724983192564 … 6.69097249831991 6.690972483255647; 6.690972491995782 6.690972509653278 … 6.690972509653941 6.690972491996452], v = [0.6972501943526237 0.6972501763775206 … 0.6972501763773445 0.6972501943524458; 0.6972502025257546 0.6972501871484955 … 0.6972501871483227 0.697250202525576; … ; 0.6972502025260159 0.697250187148757 … 0.6972501871485827 0.6972502025258378; 0.6972501943528887 0.6972501763777852 … 0.6972501763776098 0.6972501943527111]) ComponentVector{Float64}(u = [6.30178519913489 6.301785194281376 … 6.301785194281374 6.30178519913489; 6.301785162962125 6.3017851559925635 … 6.301785155992568 6.301785162962123; … ; 6.301785162962131 6.301785155992563 … 6.301785155992568 6.301785162962128; 6.301785199134893 6.30178519428138 … 6.301785194281378 6.301785199134893], v = [0.5313507880395394 0.5313507929327449 … 0.5313507929327459 0.5313507880395387; 0.5313508243693527 0.5313508313801626 … 0.5313508313801594 0.5313508243693537; … ; 0.531350824369353 0.5313508313801645 … 0.5313508313801615 0.531350824369354; 0.5313507880395402 0.5313507929327452 … 0.5313507929327462 0.5313507880395398]) ComponentVector{Float64}(u = [5.754727542805674 5.754727542926592 … 5.7547275429265925 5.754727542805674; 5.754727548485367 5.7547275489938885 … 5.7547275489938885 5.754727548485368; … ; 5.754727548485367 5.75472754899389 … 5.75472754899389 5.754727548485367; 5.754727542805675 5.754727542926591 … 5.754727542926591 5.754727542805674], v = [0.575900038678614 0.5759000385548656 … 0.5759000385548656 0.575900038678614; 0.5759000329774039 0.5759000324657239 … 0.5759000324657237 0.5759000329774039; … ; 0.5759000329774044 0.5759000324657219 … 0.5759000324657232 0.5759000329774042; 0.5759000386786137 0.5759000385548664 … 0.5759000385548657 0.5759000386786138]) ComponentVector{Float64}(u = [5.252846447930062 5.252846447198787 … 5.252846447198786 5.252846447930062; 5.252846446615069 5.252846445880636 … 5.252846445880639 5.252846446615067; … ; 5.252846446615066 5.25284644588064 … 5.252846445880641 5.252846446615067; 5.252846447930062 5.2528464471987855 … 5.2528464471987855 5.252846447930062], v = [0.6277881930500692 0.6277881937851537 … 0.6277881937851538 0.6277881930500692; 0.6277881943727248 0.627788195110997 … 0.6277881951109964 0.6277881943727249; … ; 0.6277881943727252 0.6277881951109962 … 0.627788195110996 0.6277881943727252; 0.6277881930500694 0.627788193785154 … 0.627788193785154 0.6277881930500692]) ComponentVector{Float64}(u = [4.7948227475649094 4.794822747485973 … 4.794822747485977 4.7948227475649166; 4.794822746967713 4.794822746882283 … 4.794822746882289 4.794822746967718; … ; 4.794822746967712 4.79482274688228 … 4.794822746882281 4.7948227469677125; 4.794822747564909 4.794822747485971 … 4.794822747485971 4.794822747564909], v = [0.6838289593442163 0.6838289594253382 … 0.6838289594253397 0.6838289593442176; 0.6838289599486006 0.6838289600362323 … 0.6838289600362333 0.6838289599486018; … ; 0.6838289599486054 0.683828960036234 … 0.6838289600362363 0.6838289599486053; 0.6838289593442199 0.683828959425343 … 0.6838289594253432 0.6838289593442209]) ComponentVector{Float64}(u = [4.3761461163129 4.376146116332396 … 4.376146116332398 4.376146116312906; 4.376146116352589 4.376146116372104 … 4.376146116372115 4.376146116352593; … ; 4.376146116352589 4.376146116372107 … 4.376146116372102 4.376146116352582; 4.3761461163129 4.376146116332391 … 4.376146116332385 4.376146116312892], v = [0.7442156856670751 0.7442156856473786 … 0.7442156856473828 0.7442156856670785; 0.744215685626951 0.7442156856072338 … 0.7442156856072359 0.7442156856269548; … ; 0.7442156856269597 0.7442156856072409 … 0.7442156856072445 0.7442156856269625; 0.7442156856670834 0.7442156856473882 … 0.7442156856473906 0.744215685667087]) ComponentVector{Float64}(u = [3.9927363221964227 3.992736322191407 … 3.992736322191392 3.992736322196409; 3.992736322187289 3.9927363221822687 … 3.9927363221822496 3.9927363221872816; … ; 3.9927363221872705 3.992736322182251 … 3.992736322182266 3.992736322187281; 3.9927363221963956 3.9927363221913907 … 3.9927363221914023 3.992736322196417], v = [0.809226564792118 0.8092265647971276 … 0.8092265647971163 0.8092265647921077; 0.8092265648012761 0.809226564806295 … 0.8092265648062877 0.80922656480127; … ; 0.8092265648012721 0.8092265648062913 … 0.8092265648062922 0.8092265648012749; 0.8092265647921127 0.8092265647971216 … 0.8092265647971253 0.8092265647921142]) ComponentVector{Float64}(u = [3.641198442839153 3.6411984428414166 … 3.641198442841536 3.6411984428392015; 3.6411984428420507 3.6411984428443565 … 3.6411984428444093 3.641198442842047; … ; 3.641198442842295 3.6411984428445052 … 3.6411984428443014 3.6411984428420157; 3.64119844283946 3.6411984428416466 … 3.6411984428413597 3.641198442839094], v = [0.8791285338523805 0.8791285338500484 … 0.8791285338502068 0.8791285338525285; 0.8791285338493964 0.8791285338470364 … 0.8791285338471363 0.8791285338494761; … ; 0.879128533849438 0.8791285338470806 … 0.8791285338470805 0.8791285338494393; 0.8791285338524494 0.8791285338501179 … 0.8791285338501074 0.8791285338524532]) ComponentVector{Float64}(u = [3.318462189294493 3.318462189290407 … 3.3184621892905777 3.3184621892947628; 3.3184621892859223 3.318462189281813 … 3.318462189281977 3.318462189286143; … ; 3.3184621892847974 3.3184621892807846 … 3.3184621892816515 3.318462189285716; 3.3184621892932036 3.318462189289196 … 3.3184621892901616 3.318462189294241], v = [0.9541179408785762 0.9541179408826925 … 0.9541179408825226 0.9541179408784078; 0.9541179408872338 0.9541179408913534 … 0.9541179408912281 0.9541179408871221; … ; 0.9541179408871387 0.9541179408912545 … 0.954117940891154 0.9541179408870331; 0.9541179408784524 0.954117940882566 … 0.954117940882485 0.9541179408783519]) ⋮ ComponentVector{Float64}(u = [0.4045717494457064 0.4046036148358544 … 0.4064011299587483 0.40637330039991326; 0.40456231514482965 0.40459438718211427 … 0.4063975411446074 0.4063682130135471; … ; 0.4027324648792527 0.40274009193997184 … 0.4033988871349674 0.40340014343897374; 0.40271779946577835 0.4027252394583307 … 0.4033751099136157 0.40337651576133415], v = [4.107391648931109 4.107391668325442 … 4.107393325988795 4.107393328090032; 4.1073916312563945 4.107391650662252 … 4.107393307087075 4.107393309045734; … ; 4.107388971666381 4.10738898167048 … 4.107390088987908 4.107390095114362; 4.107388950763783 4.107388960681958 … 4.107390063025338 4.1073900691848175]) ComponentVector{Float64}(u = [0.40819369321412813 0.4082255807753595 … 0.4100249393562799 0.4099971096791121; 0.40818424146189947 0.40821633567441823 … 0.41002133080523007 0.40999200234210886; … ; 0.40635178470701006 0.4063594214178449 … 0.4070192724618176 0.40702053440641883; 0.40633709917067573 0.4063445487111854 … 0.40699546867173725 0.40699688019614494], v = [4.17717335859878 4.177173355653792 … 4.177173151112326 4.177173153231475; 4.177173358607522 4.177173355670143 … 4.177173152207475 4.1771731543980986; … ; 4.177173337738257 4.17717333798029 … 4.177173375444854 4.1771733758363645; 4.177173337201026 4.177173337459752 … 4.177173376331406 4.17717337671989]) ComponentVector{Float64}(u = [0.4126136189468237 0.41264553041564805 … 0.4144468781088194 0.4144190483328714; 0.41260414834757225 0.41263626647211954 … 0.41444324824473505 0.41441391945274597; … ; 0.4107688772395943 0.41077652436852585 … 0.4114375157486952 0.41143878379048227; 0.4107541699766657 0.41076162982520853 … 0.41141368328500044 0.41141510094543415], v = [4.245758625573733 4.245758598539678 … 4.245756384646433 4.245756386755772; 4.245758644680378 4.245758617649748 … 4.2457564073354375 4.245756409746684; … ; 4.245761472999929 4.245761462702776 … 4.245760344690049 4.245760338882373; 4.2457614944514 4.24576148428149 … 4.245760374553008 4.245760368703515]) ComponentVector{Float64}(u = [0.4177800874826333 0.41781202459320727 … 0.4196155074035115 0.4195876775598058; 0.4177705966308227 0.41780274040182 … 0.4196118546397134 0.4195825255336834; … ; 0.41593230210921 0.4159399604278842 … 0.4166021772348332 0.41660345183583813; 0.41591757150740566 0.41592504242778655 … 0.4165783139863164 0.4165797382474981], v = [4.313086879306024 4.313086826435335 … 4.31308245565425 4.313082457714191; 4.313086918935214 4.313086866063521 … 4.313082501545178 4.313082504153685; … ; 4.313092808146196 4.313092786529107 … 4.313090426800745 4.313090414323985; 4.313092853218477 4.313092831847064 … 4.313090487774163 4.31309047521411]) ComponentVector{Float64}(u = [0.42366139423338417 0.4236933585243889 … 0.4254991060797909 0.4254712761972607; 0.42365188187991315 0.4236840528363149 … 0.4254954290065871 0.42546609960102993; … ; 0.4218103782481034 0.4218180484412414 … 0.4224815662750444 0.4224828478468673; 0.4217956228757184 0.42180310554571937 … 0.42245767036754767 0.4224591016435277], v = [4.379156711993842 4.3791566317374615 … 4.379149973230562 4.3791499752051735; 4.3791567734111565 4.379156693149069 … 4.379150043750662 4.379150046534942; … ; 4.379165911506981 4.379165877876093 … 4.379162199801102 4.379162180237541; 4.379165981649296 4.379165948389457 … 4.379162293777864 4.379162274087084]) ComponentVector{Float64}(u = [0.4302685224883719 0.43030051591969715 … 0.43210869080480496 0.43208086086749975; 0.43025898709585736 0.43029118719786835 … 0.43210498768500466 0.4320756579450982; … ; 0.4284140444218025 0.4284217273420483 … 0.42908663931415036 0.42908792835204784; 0.4283992625023762 0.42840675776553355 … 0.42906270840138167 0.42906414719057917], v = [4.443873567133409 4.443873457516087 … 4.4438643470502 4.443864348947216; 4.443873651895427 4.443873542267417 … 4.443864443958831 4.443864446945511; … ; 4.443886271471619 4.443886224966017 … 4.443881134301022 4.443881107147086; 4.443886368480278 4.443886322480271 … 4.4438812636516305 4.443881236323388]) ComponentVector{Float64}(u = [0.43765759171004304 0.437689616208122 … 0.43950038194706675 0.4394725520184902; 0.4376480316904113 0.43768026286468725 … 0.4394966509872161 0.4394673209588744; … ; 0.4357994144313109 0.43580711094619423 … 0.43647351314045113 0.43647481017125167; 0.435784604149979 0.43579211286519465 … 0.4364495448554722 0.4364509916876635], v = [4.507108904802143 4.507108763882259 … 4.507097036192035 4.507097037938071; 4.507109014518924 4.507108873583159 … 4.507097161307149 4.507097164440467; … ; 4.507125354160388 4.507125293901842 … 4.507118693235889 4.507118657955869; 4.507125479873154 4.507125420263408 … 4.507118860353402 4.507118824849048]) ComponentVector{Float64}(u = [0.44589636045496067 0.44592841814297224 … 0.447741952863031 0.44771412296688645; 0.44588677409991945 0.44591903846996916 … 0.44773819213535576 0.4477088618222168; … ; 0.4440342278495656 0.4440419388986266 … 0.44470993476577325 0.4447112403493481; 0.4440193872436019 0.4440269103407558 … 0.44468592653414446 0.44468738197261454], v = [4.56872264538305 4.568722471021636 … 4.568707946227704 4.568707947789746; 4.5687227817852625 4.568722607402471 … 4.568708101501617 4.568708104768654; … ; 4.56874309902146 4.568743024058995 … 4.568734808565532 4.568734764590697; 4.568743255424682 4.5687431812639225 … 4.568735016050985 4.568734971798376]) ComponentVector{Float64}(u = [0.45507805965955045 0.45511015297559265 … 0.45692666152847 0.45689883170024326; 0.45506844500224847 0.4551007450065575 … 0.4569228688116319 0.45689353822639023; … ; 0.4532116770028617 0.45321940366774693 … 0.4538891122622495 0.4538904270428415; 0.4531968038141104 0.45320434236374807 … 0.4538650611226761 0.4538665258154286], v = [4.62851667198286 4.628516461723123 … 4.628498932864358 4.628498934195332; 4.628516837063036 4.6285166267760625 … 4.628499120547568 4.6284991239240725; … ; 4.628541428196774 4.628541337437074 … 4.628531386536272 4.628531333211581; 4.628541617575122 4.628541527781188 … 4.62853163738217 4.6285315837225145])

This notebook was generated using Literate.jl.