# Modeling a leaking tank

**URL:** <https://discourse.julialang.org/t/modeling-a-leaking-tank/104750>\
**Category:** Modelling & Simulations\
**Tags:** differentialequation\
**Created:** [October 9, 2023, 12:39pm UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750 "2023-10-09T12:39:50Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![lsablon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lsablon/32/47083_2.png) [@lsablon](https://discourse.julialang.org/u/lsablon)\
**Post date:** [October 9, 2023, 12:39pm UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750/1 "2023-10-09T12:39:50Z")

</div>

Hello !

I’m currently working on modeling a system that resembles an open-topped tank with a leak, where the tank is also being supplied, so if the leak isn’t sufficient, it overflows.

The system’s equations (reasonably simple) look something like this:

V(t)' = input(t) - output(t)

with

output(t) = \begin{cases} cste,& \text{if } 0 \< V(t) \< 1\\ cste + input(t),& \text{if } V(t) \geq 1\\ 0, & \text{if } V(t) \geq 1 \end{cases} 

with the three cases: filling, overflowing, and empty.

I’ve written a small code using DifferentialEquations.jl to solve it, but the outputs aren’t _nice_, not the step function I believe it should be.  
Specifically, I’m interested in the `output(t)` function.

> **Simple reproducible code**
>
> ```julia
> input(t) = 0.5 + 0.25*sin(π*t)
> 
> function output(t, V, base_output, input)
> if 0.0 < V < 1.0
> return base_output
> elseif V >= 1.0
> return base_output .+ input(t)
> else
> return 0.0
> end
> end
> 
> function dVdt(V, p, t)
> input = p[1]
> base_output = p[2]
> 
> input(t) - output(t, V, base_output, input)
> end
> 
> base_output = 0.45
> p = (input, base_output)
> V₀ = 0.5
> 
> tspan = (0.0, 25.0)
> prob = ODEProblem(dVdt, V₀, tspan, p)
> sol = solve(prob, saveat = 0.001)
> plot(sol.t, sol.u, label="vol", ylims=(-0.1, 1.1))
> out = output.(sol.t, sol.u, base_output, input)
> plot!(sol.t, out, label="output", c=:black)
> plot!(sol.t, input.(sol.t), label="input")
> 
> ```
> 
> ![600x400](https://global.discourse-cdn.com/julialang/original/3X/4/d/4d9a98a2c2484a7597a9d4aef5fb25c9b8f37397.png)

Do any of you have a solution for this? I’d greatly appreciate your help!

Thank you!

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 9, 2023, 1:36pm UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750/2 "2023-10-09T13:36:53Z")

</div>

Hello! 👋

A few small comments

- I think you have some problem in your conditions for the output in the post (not in the code)
- Tanks with outlets often follow [Torricelli’s law](https://en.wikipedia.org/wiki/Torricelli%27s_law), is this relevant for your tank?
- The fact that `output` looks bad might be related to the dynamics being discontinuous. Try making use of a [_continuous callback_](https://docs.sciml.ai/DiffEqDocs/stable/features/callback_functions/) indicating where the discontinuities in V are

---

<div class="post-metadata">

**Author:** ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)\
**Post date:** [October 9, 2023, 1:39pm UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750/3 "2023-10-09T13:39:02Z")

</div>

In your model you assume that the outflow is constant, independently of the volume, but it is not quite realistic/physical, is it? The pressure with which the water is pushed out of the tank grows with the water level and so does the (out)flow rate (see [Torricelli’s law](https://en.wikipedia.org/wiki/Torricelli%27s_law)).

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [October 9, 2023, 3:40pm UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750/4 "2023-10-09T15:40:51Z")

</div>

> in theory there is no difference between theory and practice, while in practice there is

(ascribed to Brewster, known for Brewster angle)

If the problem of the OP is a school assignment, then it should be solved according to given conditions, whether physically sensible or not.

If it is about a real engineering system, then we know yet nothing about it.

As for Torricelli’s law - as somebody who dealt quite a lot with real life fluids and with leakages, small and large, I’d maintain that (almost) no real-life tank follows Torricelli’s law, and that approximately constant outflow can be a realistic case 🙂

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [October 9, 2023, 11:18pm UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750/5 "2023-10-09T23:18:36Z")

</div>

> [@lsablon](#):
>
> `sol = solve(prob, saveat = 0.001)`

Which solver are you using?

I use something like:

```julia
    duration=100
    tspan = (0.0, duration)
    dt = 1e-3
    ts = 0:dt:duration

    # run the simulation
    prob = ODEProblem(sys, u0, tspan, p)
    tol=1e-7
    sol = solve(prob, Rodas5(), dt=dt, abstol=tol, dtmax=1, reltol = tol, saveat=ts)

```

For discontinous problems the choice of the solver and low values for abstol and reltol are important.

---

<div class="post-metadata">

**Author:** ![lsablon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lsablon/32/47083_2.png) [@lsablon](https://discourse.julialang.org/u/lsablon)\
**Post date:** [October 10, 2023, 8:39am UTC](https://discourse.julialang.org/t/modeling-a-leaking-tank/104750/6 "2023-10-10T08:39:51Z")

</div>

I am not using any physical law at the moment because I am just exploring possible behaviors for my system (whose physical equations are unknown).

Anyway, I found a fix using low tols and removing the discrete aspect by using a very steep logistic function.

Thank you for your help 🙂
