Source code for rtdpy.convection
import numpy as np
from rtdpy.rtd import RTD, RTDInputError
[docs]class Convection(RTD):
"""
Create pure convection model for laminar flow in a pipe. [1]_
The true RTD curve is given by :math:`E(t)` for a flux-based introduction
of material and a flux-based measurment. If only one of introduction or
measurement is planar, then the apparent RTD is given by :math:`E^*(t)`.
If both introduction and measurement are planar, then the apparent RTD
is given by :math:`E^{**}(t)`.
.. math::
\\begin{align*}
E(t) &= \\frac{\\tau^2}{2t^3} & \\text{for } t\\geq\\frac{\\tau}{2}\\\\
E^*(t) &= \\frac{\\tau}{2t^2} & \\text{for } t\\geq\\frac{\\tau}{2}\\\\
E^{**}(t) &= \\frac{\\tau}{2t} & \\text{for } t\\geq\\frac{\\tau}{2}
\\end{align*}
* :math:`E(t)` is Convection.exitage
* :math:`E^*(t)` is Convection.exitage_star
* :math:`E^{**}(t)` is Convection.exitage_star2
Parameters
----------
tau : scalar
Mean residence time of true RTD.
dt : scalar
Time step for RTD. ``dt>0``
time_end : scalar
End time for RTD. ``time_end>0``
References
----------
.. [1] Levenspiel O. (1999) "Chemical Reaction Engineering: Third Edition"
John Wiley & Sons, Inc.
Examples
--------
>>> import matplotlib.pyplot as plt
>>> import rtdpy
>>> a = rtdpy.Convection(tau=1, dt=.01, time_end=2)
>>> plt.plot(a.time, a.exitage, label='E')
>>> plt.plot(a.time, a.exitage_star, label='E*')
>>> plt.plot(a.time, a.exitage_star2, label='E**')
>>> plt.xlabel('Time')
>>> plt.ylabel('Exit Age Function')
>>> plt.legend()
>>> plt.show()
"""
def __init__(self, tau, dt, time_end):
super().__init__(dt, time_end)
if tau <= 0:
raise RTDInputError("tau less than zero")
self._tau = tau
self._exitage = self._calc_exitage()
self._exitage_star = self._calc_exitage_star()
self._exitage_star2 = self._calc_exitage_star2()
def _calc_exitage(self):
"""Calculte exit age function."""
time_safe = np.clip(self.time, np.finfo(np.float).eps, None)
output = self.tau**2 / (2 * time_safe**3)
mintime = self.tau / 2
output[self.time < mintime] = 0.
return output
def _calc_exitage_star(self):
"""Calculte exit age function."""
time_safe = np.clip(self.time, np.finfo(np.float).eps, None)
output = self.tau / (2 * time_safe**2)
mintime = self.tau/2
output[self.time < mintime] = 0.
return output
@property
def exitage_star(self):
"""Planar-Flux or Flux-Planar exitage."""
return self._exitage_star
def _calc_exitage_star2(self):
"""Calculte exit age function."""
time_safe = np.clip(self.time, np.finfo(np.float).eps, None)
output = 1. / (2 * time_safe)
mintime = self.tau/2
output[self.time < mintime] = 0.
return output
@property
def exitage_star2(self):
"""Planar-Planar exitage."""
return self._exitage_star2
@property
def tau(self):
"""Mean Residence Time of **all** tanks combined."""
return self._tau
def __repr__(self):
"""Representation of object."""
return ("Convection(tau={}, dt={}, time_end={})".format(
self.tau, self.dt, self.time_end))