Source code for rtdpy.elist
from scipy.signal import convolve
from rtdpy.rtd import RTD, RTDInputError
[docs]class Elist(RTD):
"""
Create RTD model from a list of Rtd objects. Combinations of models
are convolved together. [1]_
Parameters
----------
elist : list
List of Rtd objects.
All objects must have same `dt` and `time_end`.
References
----------
.. [1] Levenspiel O. (1999) "Chemical Reaction Engineering: Third Edition"
John Wiley & Sons, Inc.
Examples
--------
>>> import matplotlib.pyplot as plt
>>> import rtdpy
>>> a = rtdpy.Ncstr(tau=1, n=1, dt=.01, time_end=15)
>>> b = rtdpy.Pfr(tau=10, dt=.01, time_end=15)
>>> c = rtdpy.Elist([a, b])
>>> plt.plot(a.time, a.exitage, label="CSTR")
>>> plt.plot(b.time, b.exitage, label="PFR")
>>> plt.ylim(0, 1.1)
>>> plt.title('Original RTD models')
>>> plt.xlabel('Time')
>>> plt.ylabel('Exit Age Function')
>>> plt.legend()
>>> plt.figure()
>>> plt.plot(c.time, c.exitage)
>>> plt.xlabel('Time')
>>> plt.ylabel('Exit Age Function')
>>> plt.title('Combination of models')
>>> plt.show()
"""
def __init__(self, elist):
"""Elist model."""
self._index = 0 # to make iterable
self._validate_rtd(elist)
dt = self._get_elist_dt(elist)
time_end = self._get_elist_time_end(elist)
super().__init__(dt=dt, time_end=time_end)
self._elist = elist
self._exitage = self._calc_exitage()
@property
def elist(self):
"""List of RTD objects."""
return self._elist
def _calc_exitage(self):
"""
Create system exit age function.
Loop all RTD models and convolve them together.
Truncate length of exit age function to keep same time_end.
"""
exitage = self.elist[0].exitage
for item in self.elist[1:]:
exitage = convolve(item.exitage, exitage) * self.dt
exitage = exitage[:len(self.time) or None]
return exitage
@staticmethod
def _validate_rtd(elist):
"""Validate that all models in elist are RTD models."""
if any([not isinstance(item, RTD) for item in elist]):
raise RTDInputError('item in list not an RTD class')
@staticmethod
def _get_elist_dt(elist):
"""Validate that all dts are the same and return dt."""
dts = [item.dt for item in elist]
if len(set(dts)) == 1:
dt = dts[0]
else:
raise RTDInputError('RTDs have inconsistent dt in Elist')
return dt
@staticmethod
def _get_elist_time_end(elist):
"""Validate that all time_ends are the same and return time_end."""
time_ends = [item.time_end for item in elist]
if len(set(time_ends)) == 1:
time_end = time_ends[0]
else:
raise RTDInputError('RTDs have inconsistent time_end in Elist')
return time_end
def __iter__(self):
"""Enable iteration."""
self._index = 0
return self
def __next__(self):
"""Implement iteration."""
try:
result = self.elist[self._index]
except IndexError:
raise StopIteration
self._index += 1
return result
def __repr__(self):
"""Representation of object."""
return ("Elist(elist={})".format(self.elist))