Creating PDEs from ODEs

Creating PDEs from ODEs#

Modeling the Brusselator PDE:

\[\begin{split} \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} \end{split}\]
import ComponentArrays.ComponentArray as CA
using SimpleUnPack
using OrdinaryDiffEq
using LinearSolve
using Plots

Initial conditions

N=26
x_min=0
y_min=0
t_min=0
x_max=1
y_max=1
t_max=11.5
α=10.0
u0 = CA(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 1:N, j in 1:N
    x = xx[j]
    y = yy[i]
    u0.u[i, j] = 22 * (y * (1 - y))
    u0.v[i, j] = 27 * (x * (1 - x))
end
u0
ComponentVector{Float64}(u = [0.0 0.0 … 0.0 0.0; 0.8447999999999999 0.8447999999999999 … 0.8447999999999999 0.8447999999999999; … ; 0.8448000000000007 0.8448000000000007 … 0.8448000000000007 0.8448000000000007; 0.0 0.0 … 0.0 0.0], v = [0.0 1.0368 … 1.0368000000000008 0.0; 0.0 1.0368 … 1.0368000000000008 0.0; … ; 0.0 1.0368 … 1.0368000000000008 0.0; 0.0 1.0368 … 1.0368000000000008 0.0])

Discretized PDE problem is a coupled ODE problem

function model(ds, s, p, t)
    @unpack α, xx, yy, dx, dy = p
    @unpack u, v = s
    brusselator_f(x, y, t) = (((x - 0.3)^2 + (y - 0.6)^2) <= 0.1^2) * (t >= 1.1) * 5

    for (i, y) in enumerate(yy), (j, x) in enumerate(xx)
        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 = (u[i, j_prev] - 2u[i, j] + u[i, j_next]) / dx^2 + (u[i_prev, j] - 2u[i, j] + u[i_next, j]) / dy^2
        vnabla = (v[i, j_prev] - 2v[i, j] + v[i, j_next]) / dx^2 + (v[i_prev, j] - 2v[i, j] + v[i_next, j]) / dy^2
        ds.u[i, j] = α * unabla + uterm
        ds.v[i, j] = α * vnabla + vterm
    end
    return nothing
end
model (generic function with 1 method)
ps = (;α, xx, yy, dx, dy)
tspan = (t_min, t_max)
prob = ODEProblem(model, u0, tspan, ps)
@time sol = solve(prob, FBDF(), saveat=0.1)
 18.900081 seconds (48.75 M allocations: 2.549 GiB, 4.82% gc time, 46.47% 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.0 … 0.0 0.0; 0.8447999999999999 0.8447999999999999 … 0.8447999999999999 0.8447999999999999; … ; 0.8448000000000007 0.8448000000000007 … 0.8448000000000007 0.8448000000000007; 0.0 0.0 … 0.0 0.0], v = [0.0 1.0368 … 1.0368000000000008 0.0; 0.0 1.0368 … 1.0368000000000008 0.0; … ; 0.0 1.0368 … 1.0368000000000008 0.0; 0.0 1.0368 … 1.0368000000000008 0.0])
 ComponentVector{Float64}(u = [6.6892071849419 6.689207178782965 … 6.689207178774696 6.6892071849335535; 6.689207183608164 6.689207176430999 … 6.689207176422823 6.689207183599775; … ; 6.689207183614746 6.689207176437695 … 6.68920717642953 6.689207183606376; 6.6892071849486365 6.689207178789639 … 6.689207178781373 6.689207184940274], v = [0.6994325977100385 0.6994326043129839 … 0.6994326043151969 0.6994325977122505; 0.6994325993278162 0.6994326069488327 … 0.6994326069509523 0.6994325993300595; … ; 0.6994325993247301 0.6994326069457236 … 0.6994326069478615 0.6994325993269667; 0.6994325977068974 0.6994326043098512 … 0.6994326043120593 0.6994325977091107])
 ComponentVector{Float64}(u = [6.301972271759478 6.30197227284435 … 6.301972272844218 6.3019722717595075; 6.301972271594038 6.301972272679893 … 6.30197227268009 6.301972271593998; … ; 6.301972271594185 6.301972272679712 … 6.301972272680075 6.301972271593946; 6.301972271759348 6.301972272844364 … 6.301972272844037 6.301972271759485], v = [0.5315881381413575 0.5315881367333056 … 0.531588136733403 0.5315881381414259; 0.5315881380618536 0.5315881366527875 … 0.5315881366528136 0.531588138061955; … ; 0.5315881380618522 0.5315881366528331 … 0.5315881366528082 0.5315881380619866; 0.5315881381413933 0.5315881367333095 … 0.531588136733434 0.5315881381414436])
 ComponentVector{Float64}(u = [5.755196733562843 5.75519673349661 … 5.7551967334993375 5.755196733564608; 5.755196733581806 5.75519673351437 … 5.755196733514295 5.755196733581242; … ; 5.755196733579967 5.755196733514724 … 5.755196733516527 5.755196733580529; 5.755196733559011 5.755196733492663 … 5.755196733494469 5.755196733562873], v = [0.5757942109933343 0.5757942110801504 … 0.5757942110801375 0.5757942109935776; 0.5757942109900249 0.5757942110763733 … 0.5757942110767204 0.575794210990214; … ; 0.5757942109908216 0.5757942110761688 … 0.575794211076437 0.5757942109901955; 0.5757942109940902 0.5757942110808355 … 0.5757942110804338 0.5757942109935846])
 ComponentVector{Float64}(u = [5.253187676257967 5.253187676263699 … 5.253187676262184 5.253187676249923; 5.253187676258682 5.253187676269005 … 5.253187676261036 5.253187676254872; … ; 5.253187676257495 5.25318767626795 … 5.253187676266392 5.253187676257679; 5.253187676259634 5.253187676266086 … 5.253187676269478 5.253187676260759], v = [0.6276860689285834 0.6276860689174202 … 0.6276860689188504 0.6276860689297843; 0.6276860689266138 0.6276860689151638 … 0.6276860689158839 0.6276860689275434; … ; 0.6276860689257269 0.6276860689135167 … 0.6276860689153657 0.627686068927295; 0.6276860689270823 0.6276860689170796 … 0.6276860689186444 0.6276860689283202])
 ComponentVector{Float64}(u = [4.794884005571883 4.7948840055532305 … 4.794884005552927 4.794884005570874; 4.7948840055772175 4.794884005556242 … 4.794884005557431 4.794884005575001; … ; 4.794884005579246 4.794884005558439 … 4.794884005557574 4.794884005575259; 4.794884005573461 4.794884005555606 … 4.794884005553161 4.794884005570676], v = [0.6838297724337183 0.6838297724574021 … 0.6838297724582908 0.6838297724347668; 0.6838297724333033 0.6838297724575456 … 0.6838297724588337 0.6838297724346765; … ; 0.6838297724322914 0.6838297724568622 … 0.6838297724582002 0.6838297724340122; 0.6838297724330239 0.683829772456269 … 0.6838297724577829 0.6838297724345902])
 ComponentVector{Float64}(u = [4.376245710071694 4.376245710066198 … 4.376245710059968 4.376245710063961; 4.376245710074479 4.3762457100680185 … 4.3762457100601075 4.376245710062231; … ; 4.376245710074223 4.376245710069717 … 4.376245710061555 4.376245710064447; 4.376245710073128 4.376245710068153 … 4.376245710062677 4.37624571006531], v = [0.7442956053589446 0.7442956053647899 … 0.7442956053725684 0.7442956053681397; 0.7442956053594652 0.7442956053659414 … 0.7442956053749049 0.7442956053695727; … ; 0.7442956053556592 0.7442956053611834 … 0.7442956053717246 0.7442956053664724; 0.7442956053560219 0.7442956053608563 … 0.7442956053713911 0.7442956053669499])
 ComponentVector{Float64}(u = [3.9932930855256235 3.993293085525426 … 3.9932930855507958 3.993293085544358; 3.9932930855223323 3.993293085530689 … 3.9932930855480113 3.9932930855504165; … ; 3.9932930855302082 3.9932930855295443 … 3.9932930855354156 3.9932930855430895; 3.9932930855275184 3.993293085527552 … 3.99329308553825 3.9932930855327897], v = [0.8092408571645079 0.809240857162367 … 0.8092408571394097 0.8092408571381868; 0.8092408571602845 0.8092408571593832 … 0.8092408571341708 0.8092408571337539; … ; 0.8092408571556288 0.809240857157878 … 0.8092408571514585 0.809240857149913; 0.809240857158317 0.8092408571577644 … 0.8092408571527896 0.8092408571530397])
 ComponentVector{Float64}(u = [3.642172490901965 3.6421724909065536 … 3.642172490897253 3.6421724908997395; 3.642172490902597 3.6421724908993123 … 3.6421724909010083 3.642172490899646; … ; 3.6421724909136515 3.64217249091509 … 3.642172490912185 3.642172490899579; 3.642172490914924 3.642172490920655 … 3.642172490903084 3.6421724909069764], v = [0.8790178561294073 0.8790178561265068 … 0.8790178561139993 0.8790178561170883; 0.879017856130424 0.8790178561268523 … 0.8790178561151978 0.8790178561180898; … ; 0.879017856131765 0.8790178561260288 … 0.8790178561164512 0.8790178561209604; 0.8790178561296041 0.8790178561261827 … 0.8790178561166039 0.8790178561177565])
 ComponentVector{Float64}(u = [3.3199291435425597 3.31992914354344 … 3.319929143545785 3.319929143545628; 3.3199291435432956 3.3199291435435048 … 3.3199291435463776 3.3199291435457576; … ; 3.3199291435502585 3.3199291435505915 … 3.3199291435454867 3.3199291435456586; 3.3199291435499743 3.3199291435498717 … 3.3199291435460823 3.319929143546792], v = [0.9539024687418923 0.9539024687420076 … 0.953902468730078 0.9539024687299806; 0.9539024687422404 0.9539024687417499 … 0.9539024687299804 0.9539024687300914; … ; 0.953902468741808 0.9539024687417872 … 0.9539024687374655 0.9539024687373356; 0.9539024687416447 0.9539024687418979 … 0.953902468737387 0.9539024687377892])
 ⋮
 ComponentVector{Float64}(u = [0.4051886240773896 0.4051791870315981 … 0.40334892770648495 0.4033342591331236; 0.40522049293882717 0.40521126253716644 … 0.40335655627184924 0.40334170061842395; … ; 0.40701829689150404 0.40701470497529607 … 0.40401551729548196 0.403991735913989; 0.4069904673198843 0.40698537679520325 … 0.40401677449484935 0.4039931426582542], v = [4.1174885139316695 4.117488499038526 … 4.117486253573453 4.11748623586898; 4.117488529827745 4.117488514949017 … 4.117486262055194 4.117486244276465; … ; 4.117489895623063 4.117489879864466 … 4.117487201378554 4.117487179621448; 4.117489897720011 4.117489881856131 … 4.117487206595771 4.117487184869734])
 ComponentVector{Float64}(u = [0.4089050137142681 0.4088955591382867 … 0.40706268039725374 0.407047991605557; 0.4089369048316443 0.4089276569119823 … 0.4070703186735373 0.4070554426933191; … ; 0.41073656086316124 0.4107329491185719 … 0.4077303408675597 0.4077065327834109; 0.4107087311943835 0.4107036206317666 … 0.4077316037232172 0.4077079452259977], v = [4.187087121693134 4.187087124563877 … 4.187087530980863 4.187087533738435; 4.187087115164905 4.187087118038822 … 4.1870875296399035 4.187087532432943; … ; 4.187086610165745 4.18708661449736 … 4.187087393618233 4.187087398843944; 4.187086612260826 4.187086616694868 … 4.187087393081481 4.1870873982974866])
 ComponentVector{Float64}(u = [0.4133716118031758 0.41336213830345747 … 0.41152643262963295 0.4115117220101738; 0.41340352693634586 0.4133942601003176 … 0.4115340813659982 0.4115191834482636; … ; 0.4152051811664246 0.4152015480280334 … 0.412195248969564 0.41217141207889524; 0.4151773513766171 0.41517221919093017 … 0.4121965179435441 0.41217283067752497], v = [4.255516840759941 4.255516862805836 … 4.255520131054346 4.255520155902128; 4.255516810033515 4.2555168320770465 … 4.255520119133001 4.25552014412651; … ; 4.255514286494755 4.255514312502886 … 4.255518822552446 4.2555188568890845; 4.255514288601403 4.255514314941014 … 4.255518815794752 4.255518850083121])
 ComponentVector{Float64}(u = [0.4185855982658704 0.4185761044591864 … 0.4167373691895856 0.41672263518662706; 0.41861753910907823 0.4186082519629467 … 0.4167450291394356 0.4167301077210007; … ; 0.42042133290325684 0.4204176767984575 … 0.41740742465514674 0.4173835569228424; 0.4203935030572168 0.4203883476538978 … 0.41740870021534476 0.4173849821493716], v = [4.322721337843276 4.322721380466515 … 4.322727715863211 4.322727764377683; 4.322721281212762 4.32272132383462 … 4.322727692595296 4.322727741372672; … ; 4.322716596360199 4.322716645635324 … 4.322725151777177 4.322725217280797; 4.322716598405461 4.322716648265539 … 4.322725138325671 4.322725203739987])
 ComponentVector{Float64}(u = [0.42453298999239364 0.4245234744454004 … 0.42268149703272767 0.4226667380159372; 0.4245649583140538 0.4245556494358043 … 0.42268916898688985 0.42267422243034225; … ; 0.42637104060032605 0.42636735992089414 … 0.4233528787951954 0.4233289780750053; 0.42634321070847936 0.4263380304731959 … 0.42335416140758875 0.42333041038437014], v = [4.3886306376101905 4.388630702262739 … 4.388640319973426 4.388640393804111; 4.388630553293171 4.388630617935448 … 4.388640284560105 4.3886403587791385; … ; 4.38862355669844 4.388623630870423 … 4.388636411967158 4.388636510805866; 4.388623558664058 4.388623633679861 … 4.388636391345084 4.388636490065726])
 ComponentVector{Float64}(u = [0.4312348828632186 0.4312253440810738 … 0.4293798975622835 0.4293651117634319; 0.43126688055368995 0.43125754844883524 … 0.42938758234938035 0.4293726088760944; … ; 0.4330754106280276 0.4330717036851275 … 0.43005269866912954 0.4300287626427365; 0.4330475806869698 0.43304237390842537 … 0.4300539888107209 0.4300302025287995], v = [4.4531483785481845 4.453148466744632 … 4.453161596417175 4.453161697352196; 4.453148264639094 4.453148352818658 … 4.45316154802292 4.45316164948163; … ; 4.453138795342193 4.453138896124296 … 4.453156250295815 4.453156384813799; 4.453138797222908 4.4531388991282315 … 4.4531562220184675 4.4531563563700765])
 ComponentVector{Float64}(u = [0.43878229371786 0.43877273006311523 … 0.4369235682122468 0.43690875371609234; 0.4388143228058263 0.43880496581762535 … 0.43693126673725013 0.4369162644167538; … ; 0.4406254720644022 0.4406217369778351 … 0.43759788988201126 0.43757391604954815; 0.4405976421663989 0.44059240692537277 … 0.43759918809165466 0.4375753640895043], v = [4.516071966830837 4.516072080232281 … 4.516088971274062 4.5160891012527795; 4.51607182128708 4.5160719346811495 … 4.516088908981859 4.516089039633178; … ; 4.51605970624594 4.516059835541505 … 4.5160820843642995 4.516082257088056; 4.516059707941269 4.516059838678659 … 4.5160820478869566 4.516082220355946])
 ComponentVector{Float64}(u = [0.4472637570101117 0.44725416653456435 … 0.4454010049349736 0.4453861595764716; 0.4472958198700191 0.447286436070134 … 0.4454087182568113 0.4453936849203148; … ; 0.4491097874642535 0.44910602206241007 … 0.4460769638539647 0.4460529493675055; 0.4490819576144844 0.449076691743083 … 0.4460782707790464 0.4460544061683713], v = [4.577152983002314 4.577153123581106 … 4.577174063861153 4.577174225074003; 4.577152803430586 4.577152943993187 … 4.577173986600672 4.5771741486410376; … ; 4.577137841441107 4.577138001449572 … 4.5771655179698065 4.577165731775685; 4.577137842933803 4.577138004700395 … 4.577165472629646 4.577165686136021])
 ComponentVector{Float64}(u = [0.45661204861831994 0.45660242954328195 … 0.4547450026745993 0.45473012440098326; 0.4566441474881723 0.4566347351023256 … 0.45475273177619907 0.4547376653618885; … ; 0.45846111989048094 0.45845732218051044 … 0.45542270772003934 0.45539864988669687; 0.458433290079296 0.4584279915594109 … 0.45542402393720705 0.45540011602492453], v = [4.636579434759678 4.63657960431636 … 4.63660486247734 4.636605057001939; 4.636579218903975 4.636579388432551 … 4.63660476925249 4.636604964768411; … ; 4.63656122148689 4.636561414228753 … 4.63659454744718 4.636594805057448; 4.63656122277546 4.636561417615834 … 4.636594492661964 4.636594749928381])

This notebook was generated using Literate.jl.