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)
 26.031544 seconds (23.84 M allocations: 1.350 GiB, 1.72% gc time, 32.70% 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.690283780136505 6.690283770473687 … 6.6902837704734965 6.690283780136311; 6.690283765108346 6.6902837560452495 … 6.6902837560450585 6.690283765108153; … ; 6.690283765107962 6.690283756044867 … 6.690283756044675 6.690283765107769; 6.690283780136116 6.690283770473295 … 6.690283770473105 6.690283780135922], v = [0.6980052707941664 0.6980052804614093 … 0.6980052804614791 0.6980052707942369; 0.6980052859183657 0.6980052949859105 … 0.6980052949859797 0.6980052859184367; … ; 0.6980052859184301 0.6980052949859754 … 0.6980052949860445 0.698005285918501; 0.6980052707942318 0.6980052804614746 … 0.6980052804615442 0.6980052707943024]) ComponentVector{Float64}(u = [6.301641741238048 6.301641736813715 … 6.301641736813717 6.301641741238047; 6.301641724144407 6.301641710867169 … 6.301641710867168 6.301641724144406; … ; 6.301641724144406 6.301641710867167 … 6.301641710867166 6.301641724144403; 6.301641741238045 6.301641736813715 … 6.301641736813714 6.301641741238045], v = [0.5315746522240604 0.5315746566716805 … 0.5315746566716809 0.5315746522240604; 0.5315746692471678 0.5315746825493439 … 0.5315746825493434 0.5315746692471683; … ; 0.531574669247168 0.5315746825493434 … 0.5315746825493439 0.531574669247168; 0.5315746522240602 0.5315746566716807 … 0.5315746566716804 0.5315746522240604]) ComponentVector{Float64}(u = [5.7549409519393695 5.754940951976714 … 5.754940951976714 5.754940951939368; 5.75494095191364 5.754940951950754 … 5.754940951950756 5.754940951913639; … ; 5.754940951913641 5.7549409519507515 … 5.754940951950757 5.754940951913639; 5.754940951939368 5.754940951976716 … 5.754940951976713 5.754940951939369], v = [0.5757193101045406 0.5757193100668017 … 0.5757193100668015 0.5757193101045407; 0.5757193101305451 0.5757193100930366 … 0.5757193100930368 0.575719310130545; … ; 0.5757193101305452 0.5757193100930363 … 0.5757193100930361 0.5757193101305452; 0.5757193101045406 0.5757193100668017 … 0.5757193100668018 0.5757193101045406]) ComponentVector{Float64}(u = [5.252818470894174 5.2528184708903884 … 5.252818470890391 5.252818470894173; 5.252818470898694 5.25281847089459 … 5.252818470894585 5.252818470898695; … ; 5.252818470898695 5.252818470894588 … 5.252818470894593 5.252818470898692; 5.252818470894174 5.25281847089039 … 5.2528184708903884 5.252818470894176], v = [0.6277636219533522 0.6277636219572748 … 0.6277636219572741 0.627763621953352; 0.6277636219488231 0.6277636219530724 … 0.6277636219530726 0.6277636219488225; … ; 0.627763621948822 0.627763621953075 … 0.6277636219530736 0.6277636219488217; 0.6277636219533528 0.6277636219572735 … 0.6277636219572735 0.627763621953352]) ComponentVector{Float64}(u = [4.794641020375762 4.794641020395988 … 4.794641020395939 4.794641020375683; 4.794641020362505 4.794641020382805 … 4.794641020382736 4.794641020362404; … ; 4.794641020362322 4.794641020382653 … 4.794641020382912 4.79464102036262; 4.79464102037557 4.7946410203958205 … 4.794641020396086 4.794641020375857], v = [0.6839175344044124 0.683917534384042 … 0.6839175343839725 0.6839175344043441; 0.683917534417703 0.683917534397263 … 0.6839175343971979 0.6839175344176379; … ; 0.683917534417712 0.6839175343972651 … 0.6839175343971458 0.6839175344175847; 0.6839175344044148 0.6839175343840417 … 0.6839175343839219 0.6839175344042892]) ComponentVector{Float64}(u = [4.376153022235081 4.376153022231734 … 4.3761530222327085 4.376153022235953; 4.376153022236825 4.376153022233496 … 4.376153022234368 4.376153022237592; … ; 4.376153022236616 4.376153022233385 … 4.376153022235293 4.376153022238632; 4.376153022234866 4.37615302223163 … 4.376153022233478 4.37615302223684], v = [0.744307657217103 0.7443076572204533 … 0.7443076572192232 0.7443076572158676; 0.7443076572153295 0.7443076572186681 … 0.7443076572174496 0.744307657214112; … ; 0.7443076572151303 0.7443076572184437 … 0.7443076572170538 0.7443076572137006; 0.7443076572168752 0.7443076572202038 … 0.7443076572188246 0.7443076572154496]) ComponentVector{Float64}(u = [3.9932098106428073 3.9932098106434504 … 3.9932098106502436 3.993209810649686; 3.9932098106423215 3.993209810642974 … 3.9932098106497103 3.9932098106491583; … ; 3.993209810645443 3.9932098106460603 … 3.993209810651038 3.9932098106503977; 3.9932098106460536 3.9932098106466705 … 3.9932098106515683 3.9932098106509066], v = [0.8092476623513014 0.8092476623506958 … 0.8092476623451209 0.8092476623456792; 0.8092476623518378 0.8092476623512384 … 0.8092476623456732 0.8092476623462236; … ; 0.8092476623504606 0.8092476623498288 … 0.8092476623445305 0.8092476623450596; 0.8092476623498903 0.8092476623492499 … 0.8092476623439696 0.8092476623445053]) ComponentVector{Float64}(u = [3.642154326397327 3.6421543263977934 … 3.642154326406 3.6421543264056564; 3.642154326397112 3.6421543263975793 … 3.642154326405752 3.6421543264054144; … ; 3.642154326401474 3.642154326401922 … 3.642154326408797 3.6421543264084413; 3.642154326401808 3.642154326402259 … 3.642154326409103 3.642154326408727], v = [0.8790187744014598 0.8790187744010948 … 0.8790187743941362 0.8790187743944138; 0.8790187744016776 0.8790187744013184 … 0.8790187743943686 0.8790187743946403; … ; 0.8790187743997914 0.8790187743994204 … 0.8790187743929325 0.8790187743931939; 0.8790187743995413 0.8790187743991633 … 0.8790187743926878 0.8790187743929544]) ComponentVector{Float64}(u = [3.3196674503312553 3.3196674503316035 … 3.3196674503352637 3.319667450334939; 3.3196674503311128 3.31966745033146 … 3.3196674503350767 3.3196674503347485; … ; 3.3196674503365626 3.3196674503369157 … 3.3196674503375507 3.319667450337306; 3.3196674503367753 3.31966745033713 … 3.3196674503377372 3.319667450337493], v = [0.9538865926778568 0.9538865926775928 … 0.9538865926759028 0.9538865926761345; 0.9538865926779774 0.953886592677709 … 0.9538865926760275 0.953886592676265; … ; 0.9538865926767965 0.95388659267654 … 0.953886592675815 0.9538865926760616; 0.9538865926766612 0.9538865926764092 … 0.953886592675688 0.9538865926759282]) ⋮ ComponentVector{Float64}(u = [0.4049305622041468 0.40496242961146606 … 0.4067601130490669 0.4067322834921344; 0.40492112630323057 0.40495320035806875 … 0.4067565224255957 0.4067271942772057; … ; 0.40309103733063595 0.4030986652743478 … 0.40375755728013774 0.40375881410356346; 0.4030763700749451 0.40308381094120677 … 0.4037337776314053 0.4037351840017613], v = [4.11310322866029 4.113103246021521 … 4.113104733605915 4.113104735695865; 4.1131032126071005 4.113103229979497 … 4.11310471653784 4.1131047185044745; … ; 4.113100794712053 4.11310080382289 … 4.11310181303951 4.113101818637841; 4.113100775674149 4.113100784708393 … 4.113101789530614 4.113101795158758]) ComponentVector{Float64}(u = [0.4086092140417766 0.4086411036564071 … 0.4104406336674843 0.41041280399403335; 0.4085997606582602 0.408631856924588 … 0.4104370232723908 0.4104076947933844; … ; 0.4067670606062694 0.40677469821683265 … 0.407434647965568 0.4074359104403459; 0.40675237319246704 0.4067598236232949 … 0.4074108417028969 0.4074122537607574], v = [4.182780787951447 4.182780782937393 … 4.182780405194378 4.182780407300076; 4.182780789613406 4.182780784606572 … 4.182780408158209 4.182780410355013; … ; 4.1827810150821625 4.1827810144138775 … 4.182780951855225 4.182780951707691; 4.182781016445275 4.182781015803132 … 4.1827809552407995 4.182780955086969]) ComponentVector{Float64}(u = [0.4130739446240562 0.41310585818368384 … 0.41490738046244163 0.41487955069088545; 0.41306447236253546 0.4130965925783047 … 0.4149037487198676 0.4148744199122754; … ; 0.41122895337790777 0.41123660142343715 … 0.4118976933861919 0.41189896196851317; 0.4112142442022358 0.4112217049578291 … 0.4118738584041831 0.41187527660850193], v = [4.251279358015244 4.25127932887499 … 4.251276938620131 4.251276940715016; 4.251279378806473 4.251279349669245 … 4.251276963212536 4.251276965629358; … ; 4.251282458083992 4.251282446859533 … 4.25128122692335 4.251281220566013; 4.251282481471341 4.251282470383711 … 4.251281259331125 4.251281252928626]) ComponentVector{Float64}(u = [0.4182923297401949 0.41832426900231096 … 0.42012793098524115 0.4201001011357951; 0.4182828371877754 0.4183149831107626 … 0.4201242762995232 0.4200949471670291; … ; 0.416444288840091 0.41645194809794844 … 0.4171142678095293 0.41711554296180275; 0.4164295562790599 0.4164370281287723 … 0.4170904019775379 0.4170918267934944], v = [4.318546828098728 4.3185467730612945 … 4.3185422213552265 4.318542223411008; 4.318546869450881 4.318546814412011 … 4.318542269192787 4.318542271817891; … ; 4.318553015579928 4.31855299301262 … 4.3185505290254165 4.3185505159884; 4.31855306263472 4.318553040322971 … 4.318550592608634 4.318550579484822]) ComponentVector{Float64}(u = [0.42422769848069464 0.4242596652228063 … 0.42606561609605925 0.42603778619069543; 0.42421818420708496 0.4242503576150866 … 0.42606193685177546 0.4260326073996586; … ; 0.42237639350757183 0.4223840647643691 … 0.42304769880860416 0.4230489809992421; 0.42236163591805004 0.4223691196403943 … 0.42302379997062833 0.4230252318694278], v = [4.384528045016493 4.384527962290789 … 4.384521098445116 4.384521100431859; 4.384528108378779 4.384528025646901 … 4.384521171164201 4.3845211739843695; … ; 4.384537536990731 4.384537502284318 … 4.384533706504793 4.384533686312272; 4.384537609376103 4.384537575052111 … 4.384533803442184 4.384533783118442]) ComponentVector{Float64}(u = [0.43091456541318135 0.4309465614646719 … 0.4327549550642978 0.43272712513220296; 0.43090502793967544 0.4309372306623097 … 0.432751249591813 0.4327219198320937; … ; 0.4290597748643746 0.4290674589326142 … 0.42973249681773684 0.429733786531881; 0.4290449905493085 0.4290524869484541 … 0.42970856274975133 0.42971000221943695], v = [4.4491387368677255 4.449138624610359 … 4.44912929320258 4.449129295082325; 4.449138823738566 4.4491387114700744 … 4.4491293924949264 4.4491293954894; … ; 4.449151757581704 4.449151709914475 … 4.449146491651787 4.449146463810398; 4.449151857015129 4.449151809865552 … 4.449146624191031 4.4491465961711]) ComponentVector{Float64}(u = [0.4383805641410123 0.4384125914499975 … 0.4402235915902592 0.4401957616619681; 0.43837100189309486 0.4384032358787668 … 0.4402198581118567 0.44019052805688746; … ; 0.43652205213093676 0.4365297498757377 … 0.43719628692653656 0.43719758468088854; 0.43650723928306645 0.4365147492153078 … 0.43717231526013156 0.43717376282045317], v = [4.512218444558843 4.51221830080689 … 4.512206336359397 4.512206338092558; 4.512218556533529 4.512218412765234 … 4.512206464025901 4.512206467173297; … ; 4.512235232800993 4.512235171297802 … 4.512228433971869 4.5122283979564335; 4.512235361111403 4.5122353002699604 … 4.5122286045062925 4.512228568261949]) ComponentVector{Float64}(u = [0.4466916584954982 0.4467237191987763 … 0.4485375054194209 0.44850967552559945; 0.4466820697491185 0.44671433713496966 … 0.4485337419884872 0.4485044116488799; … ; 0.4448291666924538 0.44483687906162017 … 0.445505019640272 0.4455063260000753; 0.44481432333244714 0.44482184773586914 … 0.4454810077801925 0.4454824639997216], v = [4.573667871372053 4.573667693972494 … 4.573652915124578 4.573652916670575; 4.573668010197314 4.573667832775872 … 4.573653073137203 4.573653076417029; … ; 4.5736886886409795 4.573688612343147 … 4.573680250224073 4.573680205460068; 4.573688847831348 4.573688772349119 … 4.573680461376188 4.573680416329587]) ComponentVector{Float64}(u = [0.4559387762608121 0.4559708727543033 … 0.45778764660447757 0.4577598167844215; 0.45592915907804427 0.4559614622603736 … 0.4577838510328791 0.4577545204255566; … ; 0.4540720143992622 0.4540797424572934 … 0.4547496038686647 0.4547509194699942; 0.4540571383033366 0.45406467823152974 … 0.45472554890094663 0.45472701441951235], v = [4.633314796833433 4.633314583372166 … 4.6332967865325685 4.633296787840984; 4.633314964472633 4.633314750983588 … 4.633296977107887 4.63329698049213; … ; 4.633339936947459 4.633339844778271 … 4.63332973902671 4.633329684867659; 4.633340129268082 4.633340038079313 … 4.633329993741047 4.633329939241961])

This notebook was generated using Literate.jl.