# MTK: PDEs & Collocation/weighted residual method

**URL:** <https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241>\
**Category:** Modelling & Simulations\
**Created:** [October 20, 2023, 2:29pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241 "2023-10-20T14:29:07Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 20, 2023, 2:29pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/1 "2023-10-20T14:29:07Z")

</div>

I’m trying to dig up some past knowledge on the “weighted residual method” – it seems to be quite similar to PINN.

How can I make the following more elegant? To exemplify, I consider a co-current heat exchanger:

\frac{\partial T\_1}{\partial t} + v\_1\frac{\partial T\_1}{\partial x} = \alpha\_1 (T\_1 - T\_2) \\ \frac{\partial T\_2}{\partial t} + v\_2\frac{\partial T\_2}{\partial x} = \alpha\_2 (T\_2 - T\_1)

with boundary conditions that T\_j(t,x=0) = T\_j^\mathrm{i}(t) are known functions of time.

The idea is to postulate “trial solutions” T\_j^\*(t,x) — these would be NN:s in PINNs, I guess. I choose trial solutions that satisfy the boundary conditions.

Next, I choose the collocation variant of weighted residual method (i.e., delta dirac weights in the “error integral”).

Here is my running code:

```julia
# Packages
using ModelingToolkit
using DifferentialEquations
using Symbolics
using Plots

# Some MTK definitions
@variables t x
Dt = Differential(t)
Dx = Differential(x)
@parameters v_1=1 α_1=0.1 v_2=2 α_2=0.5 L=10
@variables T_10(t) T_1M(t)=0 T_1L(t)=0 T_20(t)=0 T_2M(t)=0 T_2L(t)=0
#
@register_symbolic T_1i(t)
@register_symbolic T_2i(t)

# Trial solutions -- very simple for now
T_1t = T_10*(x-L)/(0 - L)*(x-L/2)/(0-L/2) + T_1M*(x-L)/(L/2 - L)*(x-0)/(L/2-0) + T_1L*(x-L/2)/(L-L/2)*(x-0)/(L-0)
T_2t = T_20*(x-L)/(0 - L)*(x-L/2)/(0-L/2) + T_2M*(x-L)/(L/2 - L)*(x-0)/(L/2-0) + T_2L*(x-L/2)/(L-L/2)*(x-0)/(L-0)

# Function for generating residuals
residual(T1,T2) = expand_derivatives.([Dt(T1) + v_1*Dx(T1) + α_1*(T1-T2),
            Dt(T2) + v_2*Dx(T2) + α_2*(T2-T1)])

# Converting actual residuals to equations
res = residual(T_1t,T_2t)

eqs = [substitute(res[1], [x => L/2]) ~ 0,
    substitute(res[1], [x => L]) ~ 0,
    substitute(res[2], [x => L/2]) ~ 0,
    substitute(res[2], [x => L]) ~ 0,
    T_10 ~ T_1i(t),
    T_20 ~ T_2i(t)]

# Symbolic model + simplified model
@named sys_ns = ODESystem(eqs,t)
sys = structural_simplify(sys_ns)

# Defining timespan + numeric problem + concrete inputs, and then solving the problem
tspan = (0,50)
#
prob = ODEProblem(sys,[],tspan)
#
T_1i(t) = t<10 ? 10 : 20
T_2i(t) = t<20 ? 5 : 15
#
sol = solve(prob, QNDF())

plot(sol)

```

Just to illustrate, the solution is as follows:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/b/cbe2724c8796869a5638d7765692b0869f03e9e6.png)

I have used simple polynomials as “basis functions” in the spatial direction x; `T_jM` is the value of the temperature midways between [0,L].

An alternative would be to use some “Finite Element” type basis functions.

**Questions**

1. How would I need to change the code to get trial solutions T\_j^\* that are real functions of time and space, which I can plot in a more elegant way? Right now, I can only plot values in the chosen collocation points (x=0, x=L/2, x=L).

2. The MOL equations for PDEs based on collocation can be generated quite fast, leading to ODEs/DAEs that can be efficiently solved using DifferentialEquations solvers. The extra cost of changing the time span is small.

- How does this compare to PINN?
- Does PINN solvers train on a specific domain in time and space, so that the training has to be completely re-done if I, e.g., extend the time span?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [October 20, 2023, 2:47pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/2 "2023-10-20T14:47:33Z")

</div>

Is there a reason why you didn’t try MethodOfLines.jl on this? That seems like it would be the most natural.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [October 20, 2023, 2:47pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/3 "2023-10-20T14:47:45Z")

</div>

> [@BLI](#):
>
> - How does this compare to PINN?
> - Does PINN solvers train on a specific domain in time and space, so that the training has to be completely re-done if I, e.g., extend the time span?

PINNs are flexible but slow

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 20, 2023, 2:55pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/4 "2023-10-20T14:55:27Z")

</div>

No real reason for not trying MOL. I just want to understand PINNs and contrast with things I already know.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [October 22, 2023, 5:11pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/5 "2023-10-22T17:11:05Z")

</div>

MethodOfLines.jl is probably the best fit here. PINNs have applications but they are odd and will not solve faster than a classical method if it’s optimized. The cases are PINNs are for where there are no optimized classical methods implemented, like high dimensional PDEs (and by high I mean like \>5), non-local operators like integro-differential equations (though there are classical techniques that should do better, just not all implementated), etc. If you do not care about the solve time and instead just want a surrogate, they can be a good surrogate model over large parameter spaces.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 22, 2023, 5:19pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/6 "2023-10-22T17:19:57Z")

</div>

For my interests, I’d consider methods where I can change the simulation time span without doing excessive re-training.

I had to remove the MethodOfLines.jl package to update ModelingToolkit.jl to a version supporting the new macros; I assume those problems perhaps have been fixed now?

---

<div class="post-metadata">

**Author:** ![xtalax](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xtalax/32/35293_2.png) [@xtalax](https://discourse.julialang.org/u/xtalax)\
**Post date:** [October 28, 2023, 4:29pm UTC](https://discourse.julialang.org/t/mtk-pdes-collocation-weighted-residual-method/105241/7 "2023-10-28T16:29:33Z")

</div>

yes I fixed that recently, our compathelper has been having problems on that repo
