CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
AllenDowney

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: AllenDowney/ModSimPy
Path: blob/master/notebooks/chap16sympy.ipynb
Views: 531
Kernel: Python 3

Modeling and Simulation in Python

SymPy code for Chapter 16

Copyright 2017 Allen Downey

License: Creative Commons Attribution 4.0 International

Mixing liquids

We can figure out the final temperature of a mixture by setting the total heat flow to zero and then solving for TT.

from sympy import * init_printing()
C1, C2, T1, T2, T = symbols('C1 C2 T1 T2 T') eq = Eq(C1 * (T - T1) + C2 * (T - T2), 0) eq

C1(TT1)+C2(TT2)=0\displaystyle C_{1} \left(T - T_{1}\right) + C_{2} \left(T - T_{2}\right) = 0

solve(eq, T)

[C1T1+C2T2C1+C2]\displaystyle \left[ \frac{C_{1} T_{1} + C_{2} T_{2}}{C_{1} + C_{2}}\right]

Analysis

We can use SymPy to solve the cooling differential equation.

T_init, T_env, r, t = symbols('T_init T_env r t') T = Function('T') eqn = Eq(diff(T(t), t), -r * (T(t) - T_env)) eqn

ddtT(t)=r(Tenv+T(t))\displaystyle \frac{d}{d t} T{\left(t \right)} = - r \left(- T_{env} + T{\left(t \right)}\right)

Here's the general solution:

solution_eq = dsolve(eqn) solution_eq

T(t)=C1ert+Tenv\displaystyle T{\left(t \right)} = C_{1} e^{- r t} + T_{env}

general = solution_eq.rhs general

C1ert+Tenv\displaystyle C_{1} e^{- r t} + T_{env}

We can use the initial condition to solve for C1C_1. First we evaluate the general solution at t=0t=0

at0 = general.subs(t, 0) at0

C1+Tenv\displaystyle C_{1} + T_{env}

Now we set T(0)=TinitT(0) = T_{init} and solve for C1C_1

solutions = solve(Eq(at0, T_init), C1) value_of_C1 = solutions[0] value_of_C1

Tenv+Tinit\displaystyle - T_{env} + T_{init}

Then we plug the result into the general solution to get the particular solution:

particular = general.subs(C1, value_of_C1) particular

Tenv+(Tenv+Tinit)ert\displaystyle T_{env} + \left(- T_{env} + T_{init}\right) e^{- r t}

We use a similar process to estimate rr based on the observation T(tend)=TendT(t_{end}) = T_{end}

t_end, T_end = symbols('t_end T_end')

Here's the particular solution evaluated at tendt_{end}

at_end = particular.subs(t, t_end) at_end

Tenv+(Tenv+Tinit)ertend\displaystyle T_{env} + \left(- T_{env} + T_{init}\right) e^{- r t_{end}}

Now we set T(tend)=TendT(t_{end}) = T_{end} and solve for rr

solutions = solve(Eq(at_end, T_end), r) value_of_r = solutions[0] value_of_r

log(Tenv+TinitTendTenv)tend\displaystyle \frac{\log{\left(\frac{- T_{env} + T_{init}}{T_{end} - T_{env}} \right)}}{t_{end}}

We can use evalf to plug in numbers for the symbols. The result is a SymPy float, which we have to convert to a Python float.

subs = dict(t_end=30, T_end=70, T_init=90, T_env=22) r_coffee2 = value_of_r.evalf(subs=subs) type(r_coffee2)
sympy.core.numbers.Float
r_coffee2 = float(r_coffee2) r_coffee2

0.011610223142273859\displaystyle 0.011610223142273859