Source code for rtdpy.ncstr

import numpy as np
from scipy import special

from rtdpy.rtd import RTD, RTDInputError


[docs]class Ncstr(RTD): """ Create N CSTR in series (N-CSTR) AKA Tank in Series Residence Time Distribution (RTD) model. [1]_ .. math:: E(t) = \\frac{1}{\\tau}\\left(\\frac{t}{\\tau}\\right)^{n-1} \\frac{n^n}{\\left(n-1\\right)!} \\text{exp}\\left[\\frac{-nt}{\\tau}\\right] Parameters ---------- tau : scalar Mean residence time of **all** CSTRs. ``tau>0`` n : scalar Number of CSTRs. Can be a real number ``n>0`` 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 >>> for n in [1, 2, 10]: ... a = rtdpy.Ncstr(tau=1, n=n, dt=.01, time_end=3) ... plt.plot(a.time, a.exitage, label=f"n={n}") >>> plt.xlabel('Time') >>> plt.ylabel('Exit Age Function') >>> plt.legend() >>> plt.show() """ def __init__(self, n, tau, dt, time_end): super().__init__(dt, time_end) if n <= 0: raise RTDInputError("n less than zero") self._n = n if tau <= 0: raise RTDInputError("tau less than zero") self._tau = tau self._exitage = self._calc_exitage() def _calc_exitage(self): """Calculte exit age function.""" output = (self.time / self.tau) ** (self.n - 1) / self.tau \ * self.n ** self.n / special.gamma(self.n) \ * np.exp(-self.time * self.n / self.tau) return output @property def n(self): """Number of CSTRS in series.""" return self._n @property def tau(self): """Mean Residence Time of **all** tanks combined.""" return self._tau def __repr__(self): """Representation of object.""" return ("Ncstr(n={}, tau={}, dt={}, time_end={})".format( self.n, self.tau, self.dt, self.time_end))