def test_failures(): with pytest.raises(rtd.RTDInputError): rtd.Ncstr(tau=-1, n=1, dt=DT, time_end=TIME_END) with pytest.raises(rtd.RTDInputError): rtd.Ncstr(tau=1, n=-1, dt=DT, time_end=TIME_END) with pytest.raises(rtd.RTDInputError): rtd.Ncstr(tau=1, n=1, dt=-1, time_end=TIME_END) with pytest.raises(rtd.RTDInputError): rtd.Ncstr(tau=1, n=1, dt=DT, time_end=-1)
def test_fail_nonmatching_dt(): a = rtdpy.Ncstr(n=1, tau=10, dt=DT, time_end=TIME_END) inputtime = a.time * 10 inputsignal = np.zeros(inputtime.size) inputsignal[inputtime > 10] = 1 with pytest.raises(rtdpy.RTDInputError): a.output(inputtime, inputsignal)
def test_ncstr(n, tau): a = rtd.Ncstr(n=n, tau=tau, dt=DT, time_end=TIME_END) assert (np.isclose(a.integral(), 1, rtol=rtol, atol=atol)) assert (np.isclose(a.mrt(), analytical_mrt(tau), rtol=rtol, atol=atol)) assert (np.isclose(a.sigma(), analytical_sigma(n, tau), rtol=rtol, atol=atol))
def test_repr(): from rtdpy import Ncstr # noqa needed for eval of repr a1 = rtd.Ncstr(n=2, tau=1, dt=DT, time_end=TIME_END) a = rtd.Elist([a1, a1]) b = eval("rtd." + repr(a)) assert np.isclose(a.integral(), b.integral(), rtol=rtol, atol=atol) assert np.isclose(a.mrt(), b.mrt(), rtol=rtol, atol=atol) assert np.isclose(a.sigma(), b.sigma(), rtol=rtol, atol=atol)
def test_iteration(): a = rtd.Ncstr(n=1, tau=1, dt=DT, time_end=TIME_END) b = rtd.Pfr(tau=1, dt=DT, time_end=TIME_END) c = rtd.Elist([a, b]) elist = [c, b, a] d = rtd.Elist(elist) for i, j in zip(elist, d): assert i == j
def test_repr(): ncstr_model = rtd.Ncstr(n=1, tau=10, dt=DT, time_end=TIME_END) def fun(t): return np.interp(t, ncstr_model.time, ncstr_model.exitage) a = rtd.Arbitrary(fun=fun, dt=DT, time_end=TIME_END) # object repr includes fun object and cannot be directly regenerated assert (repr(a))
def test_frequency_response(tau, n): def analytical_response(tau, n, omegas): return 1 / np.sqrt(1 + (omegas * tau / n)**2)**n a = rtdpy.Ncstr(tau=tau, n=n, dt=.001, time_end=100) omegas = np.logspace(-2, 2, 100) mag = a.frequencyresponse(omegas) assert np.allclose(mag, analytical_response(tau, n, omegas), rtol=rtol, atol=atol)
def test_arbitrary(): ncstr_model = rtd.Ncstr(n=1, tau=10, dt=DT, time_end=TIME_END) def fun(t): return np.interp(t, ncstr_model.time, ncstr_model.exitage) arbitrary_model = rtd.Arbitrary(fun, dt=DT, time_end=TIME_END) assert (np.isclose(arbitrary_model.integral(), 1, rtol=rtol, atol=atol)) assert (np.isclose(arbitrary_model.mrt(), 10, rtol=rtol, atol=atol)) assert (np.isclose(arbitrary_model.sigma(), 100, rtol=rtol, atol=atol))
def test_listoflist(): n = 1 tau_cstr = 10 tau_pfr = 1 a = rtd.Ncstr(n=n, tau=tau_cstr, dt=DT, time_end=TIME_END) b = rtd.Pfr(tau=tau_pfr, dt=DT, time_end=TIME_END) c = rtd.Elist([a, b]) d = rtd.Elist([c, c]) assert len(d.time) == len(d.exitage) assert (np.isclose(d.integral(), 1, rtol=rtol, atol=atol)) assert (np.isclose(d.mrt(), 22, rtol=rtol, atol=atol)) assert (np.isclose(d.sigma(), 200, rtol=rtol, atol=atol))
def test_lotsoflist_1(n): time_end = (n + 1) * 10 + np.sqrt((n + 1) * 10**2) * 4 dt = DT E = [] for i in range(n): E.append(rtd.Ncstr(n=1, tau=10, dt=dt, time_end=time_end)) f = rtd.Elist(E) assert f.time.size == f.exitage.size assert np.isclose(f.integral(), 1, rtol=rtol * 10, atol=atol) assert np.isclose(f.mrt(), (i + 1) * 10, rtol=rtol * 10, atol=atol) assert np.isclose(f.sigma(), (i + 1) * 10**2, rtol=rtol * 10, atol=atol)
def test_funnelplot(): a = rtdpy.Ncstr(tau=1, n=1, dt=.001, time_end=10) x, y, response = a.funnelplot(times=np.array([1]), disturbances=np.array([1])) x2, y2 = np.meshgrid([1], [1]) assert x == x2 assert y == y2 inputtime = a.time inputsignal = np.zeros(inputtime.size) inputsignal[inputtime < 1] = 1 outputsignal = a.output(inputtime, inputsignal) assert response[0, 0] == np.amax(outputsignal)
def test_step_output(): # test that a CSTR convolved with a step input signal # is the same as a CSTR+PFR stepresponse a = rtdpy.Ncstr(n=1, tau=10, dt=DT, time_end=TIME_END) b = rtdpy.Pfr(tau=10, dt=DT, time_end=TIME_END) c = rtdpy.Elist([a, b]) inputtime = a.time inputsignal = np.zeros(inputtime.size) inputsignal[inputtime > 10] = 1 outputsignal = a.output(inputtime, inputsignal)[:inputtime.size] assert np.allclose(outputsignal, c.stepresponse, rtol=rtol, atol=atol)
def test1(tau_cstr, tau_pfr): n = 1 a = rtd.Ncstr(n=n, tau=tau_cstr, dt=DT, time_end=TIME_END) b = rtd.Pfr(tau=tau_pfr, dt=DT, time_end=TIME_END) c = rtd.Elist([a, b]) assert len(c.time) == len(c.exitage) assert (np.isclose(c.integral(), 1, rtol=rtol, atol=atol)) assert (np.isclose(c.mrt(), analytical_mrt(tau_cstr=tau_cstr, tau_pfr=tau_pfr), rtol=rtol, atol=atol)) assert (np.isclose(c.sigma(), analytical_sigma(n=n, tau_cstr=tau_cstr), rtol=rtol, atol=atol))
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 test_repr(): a = rtd.Ncstr(n=2, tau=1, dt=DT, time_end=TIME_END) b = eval("rtd." + repr(a)) assert np.isclose(a.integral(), b.integral(), rtol=rtol, atol=atol) assert np.isclose(a.mrt(), b.mrt(), rtol=rtol, atol=atol) assert np.isclose(a.sigma(), b.sigma(), rtol=rtol, atol=atol)
def test_negative_tau_error(tau): with pytest.raises(rtd.RTDInputError): rtd.Ncstr(n=1, tau=tau, dt=1, time_end=1)
def test_negative_n_error(n): with pytest.raises(rtd.RTDInputError): rtd.Ncstr(n=n, tau=1, dt=1, time_end=1)
def test_negative_dt_error(dt): with pytest.raises(rtd.RTDInputError): rtd.Ncstr(n=1, tau=1, dt=dt, time_end=1)
def test_negative_time_end_error(time_end): with pytest.raises(rtd.RTDInputError): rtd.Ncstr(n=1, tau=1, dt=1, time_end=time_end)
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 test_exitage_norm(): a = rtdpy.Ncstr(n=1, tau=1, dt=DT, time_end=TIME_END) assert np.allclose(a.exitage_norm, a.exitage, rtol=rtol, atol=atol)
def test_exitage_norm_clipped(): a = rtdpy.Ncstr(n=1, tau=1, dt=DT, time_end=2) assert not np.isclose(a.integral(), 1, rtol=rtol, atol=atol) assert np.isclose(np.trapz(a.exitage_norm, a.time), 1, rtol=rtol, atol=atol)
def test_fail_w_nonRTD(): a = rtd.Ncstr(n=1, tau=1, dt=DT, time_end=TIME_END) with pytest.raises(rtd.RTDInputError): rtd.Elist([a, 'NCstr'])
def test_fail_w_time_end(): a = rtd.Ncstr(n=1, tau=1, dt=DT, time_end=TIME_END) b = rtd.Ncstr(n=1, tau=1, dt=DT, time_end=TIME_END * 2) with pytest.raises(rtd.RTDInputError): rtd.Elist([a, b])