Example #1
0
 def fit_func(tout, k_fw, tdelay, eps_l):
     pconv.append((k_fw, tdelay, eps_l))
     rd.k = [k_fw, k_fw/Keq]
     if tdelay > 0.0:
         integr = run(rd, c0, [0, tdelay])
         c1 = integr.Cout[1, 0, :]
     else:
         c1 = c0
     integr = run(rd, c1, tdelay+tout)
     return integr.Cout[:, 0, 2]*eps_l
Example #2
0
def test_integrate__only_1_species_diffusion__mass_conservation(N_wjac_geom_varying):
    N, wjac, geom, varying = N_wjac_geom_varying
    # Test that mass convervation is fulfilled wrt diffusion.
    x = np.linspace(0.01*N, N, N+1)
    y0 = (x[0]/2/N+x[1:]/N)**2
    if varying:
        D = np.linspace(0, (0.02*N)**0.5, N)**2
    else:
        D = [0.02*N]
    sys = ReactionDiffusion(1, [], [], [], N=N, D=D, x=x, geom=geom,
                            nstencil=3, lrefl=True, rrefl=True)

    tout = np.linspace(0, 10.0, 50)
    atol, rtol = 1e-6, 1e-8
    integr = run(sys, y0, tout, atol=atol, rtol=rtol, with_jacobian=wjac,
                 method='adams')
    yout = integr.yout[:, :, 0]
    x /= N
    if geom == 'f':
        yprim = yout*(x[1:]**1 - x[:-1]**1)
    elif geom == 'c':
        yprim = yout*(x[1:]**2 - x[:-1]**2)
    elif geom == 's':
        yprim = yout*(x[1:]**3 - x[:-1]**3)
    else:
        raise

    ybis = np.sum(yprim, axis=1)

    assert np.allclose(np.average(ybis), ybis,
                       atol=atol*(1e2 if varying else 1),
                       rtol=rtol*(1e2 if varying else 1))
Example #3
0
def main(tend=10.0, N=25, nt=30, nstencil=3, linterpol=False,
         rinterpol=False, num_jacobian=False, plot=False,
         savefig='None', verbose=False):
    x = np.linspace(0.1, 1.0, N+1)

    def f(x):
        return 2*x**2/(x**4+1)  # f(0)=0, f(1)=1, f'(0)=0, f'(1)=0
    y0 = f(x[1:])+x[0]  # (x[0]/2+x[1:])**2

    t0 = 1e-10
    tout = np.linspace(t0, tend, nt)

    res, systems = [], []
    for g in 'fcs':
        rd = ReactionDiffusion(1, [], [], [], N=N, D=[0.02], x=x,
                               geom=g, nstencil=nstencil, lrefl=not linterpol,
                               rrefl=not rinterpol)
        integr = run(rd, y0, tout, with_jacobian=(not num_jacobian))
        res.append(integr.yout)
        systems.append(rd)

    if plot:
        # matplotlib
        from mpl_toolkits.mplot3d import Axes3D
        assert Axes3D  # silence pyflakes
        from matplotlib import cm
        from matplotlib import pyplot as plt

        fig = plt.figure()

        # Plot spatio-temporal conc. evolution
        for i, g in enumerate('fcs'):
            yout = res[i]
            ax = fig.add_subplot(2, 3, 'fcs'.index(g)+1, projection='3d')

            plot_C_vs_t_and_x(rd, tout, yout, 0, ax,
                              rstride=1, cstride=1, cmap=cm.gist_earth)
            ax.set_title(Geom_names[g])

        # Plot mass conservation
        ax = fig.add_subplot(2, 3, 4)
        for j in range(3):
            ax.plot(tout, np.apply_along_axis(
                systems[j].integrated_conc, 1, res[j][:, :, 0]), label=str(j))
        ax.legend(loc='best')
        ax.set_title('Mass conservation')

        # Plot difference from flat evolution (not too informative..)
        for i, g in enumerate('fcs'):
            yout = res[i]  # only one specie
            if i != 0:
                yout = yout - res[0]  # difference (1 specie)
                ax = fig.add_subplot(2, 3, 3+'fcs'.index(g)+1, projection='3d')

                plot_C_vs_t_and_x(rd, tout, yout, 0, ax,
                                  rstride=1, cstride=1, cmap=cm.gist_earth)
                ax.set_title(Geom_names[g] + ' minus ' + Geom_names[0])

        save_and_or_show_plot(savefig)
Example #4
0
def test_get_decay_Cref():
    N = 3
    rd = _get_decay_rd(N)
    tout = np.linspace(0, 3.0, 7)
    y0 = [3.0, 1.0] * N
    integr = run(rd, y0, tout)
    Cref = _get_decay_Cref(N, y0, tout)
    assert np.allclose(Cref, integr.yout)
Example #5
0
def test_plot_C_vs_x():
    N = 3
    rd = _get_decay_rd(N)
    tout = np.linspace(0, 3.0, 7)
    y0 = [3.0, 1.0] * N
    integr = run(rd, y0, tout)
    ax = plot_C_vs_x(rd, tout, integr.yout, [0, 1], 6)
    assert isinstance(ax, matplotlib.axes.Axes)
Example #6
0
def test_plot_per_reaction_contribution():
    rd = _get_decay_rd(1)
    tout = np.linspace(0, 3.0, 7)
    y0 = [3.0, 1.0]
    integr = run(rd, y0, tout)
    axes = plot_per_reaction_contribution(integr, [0, 1])
    for ax in axes:
        assert isinstance(ax, matplotlib.axes.Axes)
Example #7
0
def test_ReactionDiffusion_fields_and_g_values(log_geom):
    # modulation in x means x_center
    # A -> B # mod1 (x**2)
    # C -> D # mod1 (x**2)
    # E -> F # mod2 (sqrt(x))
    # G -> H # no modulation
    (logy, logt, use_log2), geom = log_geom
    k = np.array([3.0, 7.0, 13.0, 22.0])
    N = 5
    n = 8
    D = np.zeros(n)
    x = np.linspace(3, 7, N+1)
    xc = x[:-1] + np.diff(x)/2
    fields = [[xc[i]*xc[i] for i in range(N)],
              [xc[i]*xc[i] for i in range(N)],
              [xc[i]**0.5 for i in range(N)]]
    g_values = [[-k[0], k[0], 0, 0, 0, 0, 0, 0],
                [0, 0, -k[1], k[1], 0, 0, 0, 0],
                [0, 0, 0, 0, -k[2], k[2], 0, 0]]
    g_value_parents = [0, 2, 4]
    rd = ReactionDiffusion(
        n,
        [[i] for i in range(n-2, n, 2)],
        [[i] for i in range(n-1, n, 2)],
        k=k[3:], N=N, D=D, x=x, fields=fields,
        g_values=g_values, g_value_parents=g_value_parents,
        logy=logy, logt=logt, geom=geom, use_log2=use_log2
    )
    assert rd.n == n
    assert rd.N == N
    assert np.allclose(rd.D[:n], D)
    assert np.allclose(rd.k, k[3:])
    assert np.allclose(rd.xcenters, xc)
    assert np.allclose(rd.fields, fields)
    assert np.allclose(rd.g_values, g_values)
    y0 = np.array([[13.0, 23.0, 32.0, 43.0, 12.0, 9.5, 17.0, 27.5]*N])
    y0 = y0.flatten()
    t0, tend, nt = 1.0, 1.1, 42
    tout = np.linspace(t0, tend, nt+1)

    integr = run(rd, y0, tout, atol=1e-11, rtol=1e-11, with_jacobian=True)

    def _get_bkf(bi, ri):
        if ri < 2:
            return xc[bi]*xc[bi]
        elif ri < 3:
            return xc[bi]**0.5
        else:
            return 1.0

    yref = np.hstack([
        np.hstack([
            np.array([
                y0[i]*np.exp(-_get_bkf(bi, i//2)*k[i//2]*(tout-t0)),
                y0[i+1]+y0[i]*(1-np.exp(-_get_bkf(bi, i//2)*k[i//2]*(tout-t0)))
            ]).transpose() for i in range(0, n, 2)
        ]) for bi in range(N)])
    assert np.allclose(integr.Cout.flatten(), yref.flatten())
Example #8
0
def test_plot_C_vs_t_and_x():
    import mpl_toolkits
    N = 3
    rd = _get_decay_rd(N)
    tout = np.linspace(0, 3.0, 7)
    y0 = [3.0, 1.0]*N
    integr = run(rd, y0, tout)
    ax = plot_C_vs_t_and_x(rd, tout, integr.yout, 0)
    assert isinstance(ax, mpl_toolkits.mplot3d.Axes3D)
Example #9
0
def test_plot_jacobian():
    # A -> B
    rd = _get_decay_rd(1)
    y0 = [3.0, 1.0]
    tout = np.linspace(0, 3.0, 7)
    integr = run(rd, y0, tout)
    axes = plot_jacobian(rd, integr.tout, integr.yout, [0, 1])
    for ax in axes:
        assert isinstance(ax, matplotlib.axes.Axes)
Example #10
0
def test_plot_solver_linear_excess_error():
    N = 3
    rd = _get_decay_rd(N)
    tout = np.linspace(0, 3.0, 7)
    y0 = [3.0, 1.0] * N
    integr = run(rd, y0, tout)
    Cref = _get_decay_Cref(N, y0, tout)
    ax = plot_solver_linear_excess_error(integr, Cref)
    assert isinstance(ax, matplotlib.axes.Axes)
Example #11
0
def simulate_stopped_flow(rd, t, c0, k, noiselvl, eps_l, tdelay=None):
    if tdelay is None:
        tdelay = np.abs(np.random.normal(
            t[-1]/20, scale=t[-1]/20))
    integr = run(rd, c0, t)
    ytrue = eps_l*integr.Cout[:, 0, 2]
    skip_nt = np.argwhere(t >= tdelay)[0]
    tinp = t[:-skip_nt] if skip_nt > 0 else t
    yinp = ytrue[skip_nt:] + noiselvl*np.random.normal(
        size=len(t)-skip_nt)
    return tinp, yinp
Example #12
0
def test_decay(log):
    # A -> B
    n = 2
    logy, logt, use_log2 = log
    k0 = 0.13
    rd = ReactionDiffusion(n, [[0]], [[1]], k=[k0], logy=logy, logt=logt, use_log2=use_log2)
    y0 = [3.0, 1.0]
    t0, tend, nt = 5.0, 17.0, 42
    tout = np.linspace(t0, tend, nt+1)

    integr = run(rd, y0, tout)
    yref = np.array([y0[0]*np.exp(-k0*(tout-t0)),
                     y0[1]+y0[0]*(1-np.exp(-k0*(tout-t0)))]).transpose()
    assert np.allclose(integr.Cout[:, 0, :], yref)
def main(tend=3.0, N=30, nt=30, plot=False, logy=False, logt=False,
         savefig='None', verbose=False):
    def mod1(x):
        return x/(x**2+1)

    # decay A->B is modulated with x
    rd = load(
        os.path.join(os.path.dirname(
            __file__), 'four_species.json'),
        N=N, modulation=[[mod1(x/3+0.1) for x in range(N)]],
        modulated_rxns=[1], logt=logt, logy=logy)

    y0 = np.array([1.3, 1e-4, 0.7, 1e-4])
    # y0 = np.concatenate([y0/(i+1)*(0.25*i**2+1) for i in range(N)])
    y0 = np.concatenate([y0 for i in range(N)])

    t0 = 1e-10
    tout = np.linspace(t0, tend, nt)
    integr = run(rd, y0, tout)
    if verbose:
        pprint(integr.info)

    cx = rd.x[:-1]+np.diff(rd.x)/2  # center x
    if plot:
        # Using matplotlib for 3D plots:
        from mpl_toolkits.mplot3d import Axes3D
        assert Axes3D  # silence pyflakes
        from matplotlib import cm
        from matplotlib import pyplot as plt

        from chemreac.util.plotting import save_and_or_show_plot

        fig = plt.figure()

        for i, l in enumerate('ABCD'):
            ax = fig.add_subplot(3, 2, i+1, projection='3d')
            T, X = np.meshgrid(cx, tout)
            ax.plot_surface(T, X, integr.Cout[:, :, i], rstride=1, cstride=1,
                            cmap=cm.YlGnBu_r)
            ax.set_xlabel('x / m')
            ax.set_ylabel('time / s')
            ax.set_zlabel(r'C / mol*m**-3')
            ax.set_title(l)
            ax.legend(loc='best')

        ax = fig.add_subplot(3, 2, 5)
        print(np.array(rd.modulation).shape)
        ax.plot(cx, np.array(rd.modulation)[0, :])

        save_and_or_show_plot(savefig=savefig)
Example #14
0
def _test_integrate(params):
    logy, logt, N, geom, use_log2 = params
    rd = load(JSON_PATH, N=N, logy=logy, logt=logt, geom=geom, use_log2=use_log2)
    assert rd.geom == geom
    y0 = np.array(C0*N)

    ref = np.genfromtxt(BLESSED_PATH)
    ref_t = ref[:, 0]
    ref_y = ref[:, 1:rd.n+1]

    t0 = 3.0
    tend = 5.0+t0
    nt = 137
    tout = np.linspace(t0, tend, nt+1)
    assert np.allclose(tout-t0, ref_t)

    _test_f_and_dense_jac_rmaj(rd, t0, rd.logb(y0) if logy else y0)
    integr = run(rd, y0, tout, with_jacobian=True)
    for i in range(N):
        assert np.allclose(integr.Cout[:, i, :], ref_y, atol=1e-4)
Example #15
0
def main(tdelay=1.0, B0=0.6, noiselvl=3e-4, nt=200, eps_l=4200.0, plot=False):
    """
    Solution:
      1. non-linear fit to:
       A) if approx equal conc A+A -> C
       B) else: A+B -> C
      2. Use as guess for guess and shoot. A + B <-> C
    """
    Keq = 10.0
    k_fw_true = 1.3
    ktrue = [1.3, k_fw_true/Keq]

    c0 = [1.0, B0, 0.0]
    ttrue = np.linspace(0, 10, nt)
    rd_eq = ReactionDiffusion(3, [[0, 1], [2]], [[2], [0, 1]], k=ktrue)
    tinp, yinp = simulate_stopped_flow(
        rd_eq, ttrue, c0, ktrue, noiselvl, eps_l, tdelay)
    k_fw_opt, d_opt, eps_l_opt = fit_binary_eq_from_temporal_abs_data(
        tinp, yinp, c0, Keq, True)

    rd_eq.k = [k_fw_opt, k_fw_opt/Keq]
    integr = run(rd_eq, c0, ttrue)
    yopt = integr.Cout[:, 0, 2]*eps_l_opt

    if plot:
        import matplotlib.pyplot as plt
        # Plot
        plt.subplot(2, 1, 1)
        plt.plot(tinp, yinp, label='Input data')
        plt.plot(ttrue-tdelay, yopt,
                 label='Shooting Opt (k={})'.format(k_fw_opt))
        plt.legend(loc='best')

        plt.subplot(2, 1, 2)
        plt.plot(tinp, yinp, label='Input data')
        # TODO: this needs to be improved...
        yquad = (B0-1/(1/B0+k_fw_opt*ttrue))*eps_l_opt
        plt.plot(ttrue-tdelay, yquad, label='Equal initial conc treatment')
        plt.legend(loc='best')
        plt.show()
def integrate_rd(t0=1e-7,
                 tend=.1,
                 doserate=15,
                 N=1000,
                 nt=512,
                 nstencil=3,
                 logy=False,
                 logt=False,
                 num_jacobian=False,
                 savefig='None',
                 verbose=False,
                 plot=False,
                 plot_jacobians=False):
    null_conc = 1e-24

    mu = 1.0  # linear attenuation
    rho = 1.0  # kg/dm3
    rd = load(os.path.join(os.path.dirname(__file__),
                           'aqueous_radiolysis.json'),
              ReactionDiffusion,
              N=N,
              logy=logy,
              logt=logt,
              bin_k_factor=[[doserate * rho * exp(-mu * i / N)]
                            for i in range(N)],
              nstencil=nstencil)
    y0_by_name = json.load(
        open(
            os.path.join(os.path.dirname(__file__),
                         'aqueous_radiolysis.y0.json'), 'rt'))

    # y0 with a H2 gradient
    y0 = np.array([[
        y0_by_name.get(k, null_conc) if k != 'H2' else 1e-3 / (i + 2)
        for k in rd.substance_names
    ] for i in range(rd.N)])

    tout = np.logspace(log(t0), log(tend), nt + 1, base=e)
    integr = run(rd, y0, tout, with_jacobian=(not num_jacobian))
Example #17
0
def test_autodimerization(arrhenius):
    # A + A -> B
    from chemreac.chemistry import (
        Reaction, ReactionSystem, mk_sn_dict_from_names
    )
    sbstncs = mk_sn_dict_from_names('AB')
    if arrhenius:
        from chempy.kinetics.arrhenius import ArrheniusParam
        k = ArrheniusParam(7e11, -8.314472*298.15*(np.log(3) - np.log(7) - 11*np.log(10)))
        variables = {'temperature': 298.15}
        param = 3.0
    else:
        param = k = 3.0
        variables = None
    r1 = Reaction({'A': 2}, {'B': 1}, k)
    rsys = ReactionSystem([r1], sbstncs)
    rd = ReactionDiffusion.from_ReactionSystem(rsys, variables=variables)
    t = np.linspace(0, 5, 3)
    A0, B0 = 1.0, 0.0
    integr = run(rd, [A0, B0], t)
    Aref = 1/(1/A0+2*param*t)
    yref = np.vstack((Aref, (A0-Aref)/2)).transpose()
    assert np.allclose(integr.yout[:, 0, :], yref)
Example #18
0
def integrate_rd(N=64, geom='f', nspecies=1, nstencil=3,
                 D=2e-3, t0=3.0, tend=7., x0=0.0, xend=1.0, center=None,
                 nt=42, logt=False, logy=False, logx=False,
                 random=False, p=0, a=0.2,
                 linterpol=False, rinterpol=False, ilu_limit=5.0,
                 n_jac_diags=-1, num_jacobian=False,
                 method='bdf', integrator='cvode', iter_type='undecided',
                 linear_solver='default',
                 atol=1e-8, rtol=1e-10,
                 efield=False, random_seed=42, mobility=0.01,
                 plot=False, savefig='None', verbose=False, yscale='linear',
                 vline_limit=100, use_log2=False, Dexpr='[D]*nspecies', check_conserv=False
                 ):  # remember: anayltic_N_scaling.main kwargs
    # Example:
    # python3 analytic_diffusion.py --plot --Dexpr "D*np.exp(10*(x[:-1]+np.diff(x)/2))"
    if t0 == 0.0:
        raise ValueError("t0==0 => Dirac delta function C0 profile.")
    if random_seed:
        np.random.seed(random_seed)
    # decay = (nspecies > 1)
    # n = 2 if decay else 1
    center = float(center or x0)
    tout = np.linspace(t0, tend, nt)

    assert geom in 'fcs'
    analytic = {
        'f': flat_analytic,
        'c': cylindrical_analytic,
        's': spherical_analytic
    }[geom]

    # Setup the grid
    logx0 = math.log(x0) if logx else None
    logxend = math.log(xend) if logx else None
    if logx and use_log2:
        logx0 /= math.log(2)
        logxend /= math.log(2)
    _x0 = logx0 if logx else x0
    _xend = logxend if logx else xend
    x = np.linspace(_x0, _xend, N+1)
    if random:
        x += (np.random.random(N+1)-0.5)*(_xend-_x0)/(N+2)

    def _k(si):
        return (si+p)*math.log(a+1)
    k = [_k(i+1) for i in range(nspecies-1)]
    rd = ReactionDiffusion(
        nspecies,
        [[i] for i in range(nspecies-1)],
        [[i+1] for i in range(nspecies-1)],
        k,
        N,
        D=eval(Dexpr),
        z_chg=[1]*nspecies,
        mobility=[mobility]*nspecies,
        x=x,
        geom=geom,
        logy=logy,
        logt=logt,
        logx=logx,
        nstencil=nstencil,
        lrefl=not linterpol,
        rrefl=not rinterpol,
        ilu_limit=ilu_limit,
        n_jac_diags=n_jac_diags,
        use_log2=use_log2
    )

    if efield:
        if geom != 'f':
            raise ValueError("Only analytic sol. for flat drift implemented.")
        rd.efield = _efield_cb(rd.xcenters)

    # Calc initial conditions / analytic reference values
    t = tout.copy().reshape((nt, 1))
    yref = analytic(rd.xcenters, t, D, center, x0, xend,
                    -mobility if efield else 0, logy, logx, use_log2).reshape(nt, N, 1)

    if nspecies > 1:
        from batemaneq import bateman_parent
        bateman_out = np.array(bateman_parent(k, tout)).T
        terminal = (1 - np.sum(bateman_out, axis=1)).reshape((nt, 1))
        bateman_out = np.concatenate((bateman_out, terminal), axis=1).reshape(
            (nt, 1, nspecies))
        if logy:
            yref = yref + rd.logb(bateman_out)
        else:
            yref = yref * bateman_out

    # Run the integration
    integr = run(rd, yref[0, ...], tout, atol=atol, rtol=rtol,
                 with_jacobian=(not num_jacobian), method=method,
                 iter_type=iter_type, linear_solver=linear_solver,
                 C0_is_log=logy, integrator=integrator)
    info = integr.info

    if logy:
        def lin_err(i, j):
            linref = rd.expb(yref[i, :, j])
            linerr = rd.expb(integr.yout[i, :, j])-linref
            linatol = np.average(yref[i, :, j])
            linrtol = linatol
            return linerr/(linrtol*np.abs(linref)+linatol)

    if logy:
        rmsd = np.sum(lin_err(slice(None), slice(None))**2 / N, axis=1)**0.5
    else:
        rmsd = np.sum((yref-integr.yout)**2 / N, axis=1)**0.5
    ave_rmsd_over_atol = np.average(rmsd, axis=0)/atol

    if verbose:
        # Print statistics
        from pprint import pprint
        pprint(info)
        pprint(ave_rmsd_over_atol)

    # Plot results
    if plot:
        import matplotlib.pyplot as plt
        plt.figure(figsize=(6, 10))

        # colors: (0.5, 0.5, 0.5), (0.5, 0.5, 1), ...
        base_colors = list(product([.5, 1], repeat=3))[1:-1]

        def color(ci, ti):
            return np.array(base_colors[ci % len(base_colors)])*tout[ti]/tend

        for ti in range(nt):
            plt.subplot(4, 1, 1)
            for si in range(nspecies):
                plt.plot(rd.xcenters, integr.Cout[ti, :, si], c=color(si, ti),
                         label=None if ti < nt - 1 else rd.substance_names[si])

            plt.subplot(4, 1, 2)
            for si in range(nspecies):
                plt.plot(rd.xcenters, rd.expb(yref[ti, :, si]) if logy
                         else yref[ti, :, si], c=color(si, ti))

            plt.subplot(4, 1, 3)
            if logy:
                for si in range(nspecies):
                    plt.plot(rd.xcenters, lin_err(ti, si)/atol,
                             c=color(si, ti))
            else:
                for si in range(nspecies):
                    plt.plot(
                        rd.xcenters,
                        (yref[ti, :, si] - integr.yout[ti, :, si])/atol,
                        c=color(si, ti))

        if N < vline_limit:
            for idx in range(1, 4):
                plt.subplot(4, 1, idx)
                for bi in range(N):
                    plt.axvline(rd.x[bi], color='gray')

        plt.subplot(4, 1, 1)
        plt.title('Simulation (N={})'.format(rd.N))
        plt.xlabel('x / m')
        plt.ylabel('C / M')
        plt.gca().set_yscale(yscale)
        plt.legend()

        plt.subplot(4, 1, 2)
        plt.title('Analytic solution')
        plt.gca().set_yscale(yscale)

        plt.subplot(4, 1, 3)
        plt.title('Linear rel. error / Abs. tol. (={})'.format(atol))

        plt.subplot(4, 1, 4)
        plt.title('RMS error vs. time'.format(atol))
        tspan = [tout[0], tout[-1]]
        for si in range(nspecies):
            plt.plot(tout, rmsd[:, si] / atol, c=color(si, -1))
            plt.plot(tspan, [ave_rmsd_over_atol[si]]*2,
                     c=color(si, -1), ls='--')

        plt.xlabel('Time / s')
        plt.ylabel(r'$\sqrt{\langle E^2 \rangle} / atol$')
        plt.tight_layout()
        save_and_or_show_plot(savefig=savefig)

    if check_conserv:
        tot_amount = np.zeros(tout.size)
        for ti in range(tout.size):
            for si in range(nspecies):
                tot_amount[ti] += rd.integrated_conc(integr.yout[ti, :, si])
        if plot:
            plt.plot(tout, tot_amount)
            plt.show()
        assert np.allclose(tot_amount[0], tot_amount[1:])

    return tout, integr.yout, info, ave_rmsd_over_atol, rd, rmsd
Example #19
0
def integrate_rd(D=-3e-1, t0=0.0, tend=7., x0=0.1, xend=1.0, N=1024,
                 base=0.5, offset=0.25, nt=25, geom='f',
                 logt=False, logy=False, logx=False, random=False,
                 nstencil=3, lrefl=False, rrefl=False,
                 num_jacobian=False, method='bdf', plot=False,
                 savefig='None', atol=1e-6, rtol=1e-6, random_seed=42,
                 surf_chg=(0.0, 0.0), sigma_q=101, sigma_skew=0.5,
                 verbose=False, eps_rel=80.10, use_log2=False):
    """
    A negative D (diffusion coefficent) denotes:
        mobility := -D
        D := 0
    A positive D calculates mobility from Einstein-Smoluchowski relation

    """
    assert 0 <= base and base <= 1
    assert 0 <= offset and offset <= 1
    if random_seed:
        np.random.seed(random_seed)
    n = 2

    if D < 0:
        mobility = -D
        D = 0
    else:
        mobility = electrical_mobility_from_D(D, 1, 298.15)
        print(D, mobility)

    # Setup the grid
    logb = (lambda arg: log(arg)/log(2)) if use_log2 else log

    _x0 = logb(x0) if logx else x0
    _xend = logb(xend) if logx else xend
    x = np.linspace(_x0, _xend, N+1)
    if random:
        x += (np.random.random(N+1)-0.5)*(_xend-_x0)/(N+2)

    # Setup the system
    stoich_active = []
    stoich_prod = []
    k = []

    rd = ReactionDiffusion(
        n, stoich_active, stoich_prod, k, N,
        D=[D, D],
        z_chg=[1, -1],
        mobility=[mobility, -mobility],
        x=x,
        geom=geom,
        logy=logy,
        logt=logt,
        logx=logx,
        nstencil=nstencil,
        lrefl=lrefl,
        rrefl=rrefl,
        auto_efield=True,
        surf_chg=surf_chg,
        eps_rel=eps_rel,  # water at 20 deg C
        faraday_const=1,
        vacuum_permittivity=1,
        use_log2=use_log2
    )

    # Initial conditions
    sigma = (xend-x0)/sigma_q
    sigma = [(1-sigma_skew)*sigma, sigma_skew*sigma]
    y0 = np.vstack(pair_of_gaussians(
        rd.xcenters, [base+offset, base-offset], sigma, logy, logx, geom, use_log2)).transpose()
    if logy:
        y0 = sigm(y0)

    if plot:
        # Plot initial E-field
        import matplotlib.pyplot as plt
        plt.figure(figsize=(6, 10))
        rd.calc_efield((rd.expb(y0) if logy else y0).flatten())
        plt.subplot(4, 1, 3)
        plt.plot(rd.xcenters, rd.efield, label="E at t=t0")
        plt.plot(rd.xcenters, rd.xcenters*0, label="0")

    # Run the integration
    tout = np.linspace(t0, tend, nt)
    integr = run(rd, y0, tout,
                 atol=atol, rtol=rtol, sigm_damp=True,
                 C0_is_log=logy,
                 with_jacobian=(not num_jacobian), method=method)
    Cout = integr.Cout

    if verbose:
        print(integr.info)
    # Plot results
    if plot:
        def _plot(y, ttl=None,  **kwargs):
            plt.plot(rd.xcenters, y, **kwargs)
            plt.xlabel((('log_%s({})' % ('2' if use_log2 else 'e')) if logx else '{}').format('x / m'))
            plt.ylabel('C / M')
            if ttl:
                plt.title(ttl)

        for i in range(nt):
            plt.subplot(4, 1, 1)
            c = 1-tout[i]/tend
            c = (1.0-c, .5-c/2, .5-c/2)
            _plot(Cout[i, :, 0], 'Simulation (N={})'.format(rd.N),
                  c=c, label='$z_A=1$' if i == nt-1 else None)
            _plot(Cout[i, :, 1], c=c[::-1],
                  label='$z_B=-1$' if i == nt-1 else None)
            plt.legend()

            plt.subplot(4, 1, 2)
            delta_y = Cout[i, :, 0] - Cout[i, :, 1]
            _plot(delta_y, 'Diff'.format(rd.N),
                  c=[c[2], c[0], c[1]],
                  label='A-B (positive excess)' if i == nt-1 else None)
            plt.legend(loc='best')
            plt.xlabel("$x~/~m$")
            plt.ylabel(r'Concentration / M')
        ylim = plt.gca().get_ylim()
        if N < 100:
            plt.vlines(rd.x, ylim[0], ylim[1],
                       linewidth=1.0, alpha=0.2, colors='gray')

        plt.subplot(4, 1, 3)
        plt.plot(rd.xcenters, rd.efield, label="E at t=tend")
        plt.xlabel("$x~/~m$")
        plt.ylabel("$E~/~V\cdot m^{-1}$")
        plt.legend()

        for i in range(3):
            plt.subplot(4, 1, i+1)
            ylim = plt.gca().get_ylim()
            for d in (-1, 1):
                center_loc = [x0+(base+d*offset)*(xend-x0)]*2
                plt.plot(rd.logb(center_loc) if logx else center_loc,
                         ylim, '--k')
        plt.subplot(4, 1, 4)
        for i in range(n):
            amount = [rd.integrated_conc(Cout[j, :, i]) for j in range(nt)]
            plt.plot(tout, amount, c=c[::(1, -1)[i]], label=chr(ord('A')+i))
        plt.xlabel('Time / s')
        plt.ylabel('Amount / mol')
        plt.legend(loc='best')
        plt.tight_layout()
        save_and_or_show_plot(savefig=savefig)
    return tout, Cout, integr.info, rd
def integrate_rd(D=2e-3, t0=3., tend=7., x0=0.0, xend=1.0, mu=None, N=64,
                 nt=42, geom='f', logt=False, logy=False, logx=False,
                 random=False, k=0.0, nstencil=3, linterpol=False,
                 rinterpol=False, num_jacobian=False, method='bdf',
                 scale_x=False, atol=1e-6, rtol=1e-6,
                 efield=False, random_seed=42):
    if t0 == 0.0:
        raise ValueError("t0==0 => Dirac delta function C0 profile.")
    if random_seed:
        np.random.seed(random_seed)
    decay = (k != 0.0)
    n = 2 if decay else 1
    mu = float(mu or x0)
    tout = np.linspace(t0, tend, nt)

    assert geom in 'fcs'
    geom = {'f': FLAT, 'c': CYLINDRICAL, 's': SPHERICAL}[geom]
    analytic = {
        FLAT: flat_analytic,
        CYLINDRICAL: cylindrical_analytic,
        SPHERICAL: spherical_analytic
    }[geom]

    # Setup the grid
    _x0 = log(x0) if logx else x0
    _xend = log(xend) if logx else xend
    x = np.linspace(_x0, _xend, N+1)
    if random:
        x += (np.random.random(N+1)-0.5)*(_xend-_x0)/(N+2)

    rd = ReactionDiffusion(
        2 if decay else 1,
        [[0]] if decay else [],
        [[1]] if decay else [],
        [k] if decay else [],
        N,
        D=[D]*(2 if decay else 1),
        z_chg=[1]*(2 if decay else 1),
        mobility=[0.01]*(2 if decay else 1),
        x=x,
        geom=geom,
        logy=logy,
        logt=logt,
        logx=logx,
        nstencil=nstencil,
        lrefl=not linterpol,
        rrefl=not rinterpol,
        xscale=1/(x[1]-x[0]) if scale_x else 1.0
    )

    if efield:
        if geom != FLAT:
            raise ValueError("Only analytic sol. for flat drift implemented.")
        rd.efield = _efield_cb(rd.xcenters)

    # Calc initial conditions / analytic reference values
    t = tout.copy().reshape((nt, 1))
    yref = analytic(rd.xcenters, t, D, mu, x0, xend,
                    0.01 if efield else 0, logy, logx).reshape(nt, N, 1)

    if decay:
        yref = np.concatenate((yref, yref), axis=2)
        if logy:
            yref[:, :, 0] += -k*t
            yref[:, :, 1] += np.log(1-np.exp(-k*t))
        else:
            yref[:, :, 0] *= np.exp(-k*t)
            yref[:, :, 1] *= 1-np.exp(-k*t)

    # Run the integration
    integr = run(rd, yref[0, ...], tout, atol=atol, rtol=rtol,
                 with_jacobian=(not num_jacobian), method=method,
                 C0_is_log=logy)
Example #21
0
def integrate_rd(D=2e-3,
                 t0=3.,
                 tend=7.,
                 x0=0.0,
                 xend=1.0,
                 mu=None,
                 N=64,
                 nt=42,
                 geom='f',
                 logt=False,
                 logy=False,
                 logx=False,
                 random=False,
                 k=0.0,
                 nstencil=3,
                 linterpol=False,
                 rinterpol=False,
                 num_jacobian=False,
                 method='bdf',
                 scale_x=False,
                 atol=1e-6,
                 rtol=1e-6,
                 efield=False,
                 random_seed=42):
    if t0 == 0.0:
        raise ValueError("t0==0 => Dirac delta function C0 profile.")
    if random_seed:
        np.random.seed(random_seed)
    decay = (k != 0.0)
    n = 2 if decay else 1
    mu = float(mu or x0)
    tout = np.linspace(t0, tend, nt)

    assert geom in 'fcs'
    geom = {'f': FLAT, 'c': CYLINDRICAL, 's': SPHERICAL}[geom]
    analytic = {
        FLAT: flat_analytic,
        CYLINDRICAL: cylindrical_analytic,
        SPHERICAL: spherical_analytic
    }[geom]

    # Setup the grid
    _x0 = log(x0) if logx else x0
    _xend = log(xend) if logx else xend
    x = np.linspace(_x0, _xend, N + 1)
    if random:
        x += (np.random.random(N + 1) - 0.5) * (_xend - _x0) / (N + 2)

    rd = ReactionDiffusion(2 if decay else 1, [[0]] if decay else [],
                           [[1]] if decay else [], [k] if decay else [],
                           N,
                           D=[D] * (2 if decay else 1),
                           z_chg=[1] * (2 if decay else 1),
                           mobility=[0.01] * (2 if decay else 1),
                           x=x,
                           geom=geom,
                           logy=logy,
                           logt=logt,
                           logx=logx,
                           nstencil=nstencil,
                           lrefl=not linterpol,
                           rrefl=not rinterpol,
                           xscale=1 / (x[1] - x[0]) if scale_x else 1.0)

    if efield:
        if geom != FLAT:
            raise ValueError("Only analytic sol. for flat drift implemented.")
        rd.efield = _efield_cb(rd.xcenters)

    # Calc initial conditions / analytic reference values
    t = tout.copy().reshape((nt, 1))
    yref = analytic(rd.xcenters, t, D, mu, x0, xend, 0.01 if efield else 0,
                    logy, logx).reshape(nt, N, 1)

    if decay:
        yref = np.concatenate((yref, yref), axis=2)
        if logy:
            yref[:, :, 0] += -k * t
            yref[:, :, 1] += np.log(1 - np.exp(-k * t))
        else:
            yref[:, :, 0] *= np.exp(-k * t)
            yref[:, :, 1] *= 1 - np.exp(-k * t)

    # Run the integration
    integr = run(rd,
                 yref[0, ...],
                 tout,
                 atol=atol,
                 rtol=rtol,
                 with_jacobian=(not num_jacobian),
                 method=method,
                 C0_is_log=logy)
Example #22
0
def integrate_rd(tend=2.0, A0=1.0, nt=67, t0=0.0,
                 rates='3.40715,4.0', logy=False, logt=False,
                 plot=False, savefig='None', method='bdf',
                 atol='1e-7,1e-6,1e-5', rtol='1e-6', sigm_damp=False,
                 num_jac=False, scale_err=1.0, small='None', use_log2=False,
                 plotlogy=False, plotlogt=False, verbose=False):
    """
    Analytic solution through Bateman equation =>
    ensure :math:`|k_i - k_j| \gg eps`
    """
    k = list(map(float, rates.split(',')))
    n = len(k)+1
    if n > 4:
        raise ValueError("Max 3 consequtive decays supported at the moment.")

    atol = list(map(float, atol.split(',')))
    if len(atol) == 1:
        atol = atol[0]
    rtol = float(rtol)

    rd = ReactionDiffusion(
        n, [[i] for i in range(n-1)], [[i] for i in range(1, n)],
        k, logy=logy, logt=logt, use_log2=use_log2)

    y0 = np.zeros(n)
    y0[0] = A0
    if small == 'None':
        tiny = None
    else:
        tiny = 0
        y0 += float(small)
    tout = np.linspace(t0, tend, nt)
    integr = run(rd, y0, tout, atol=atol, rtol=rtol, method=method,
                 with_jacobian=not num_jac, sigm_damp=sigm_damp, tiny=tiny)
    Cout, yout, info = integr.Cout, integr.yout, integr.info
    Cref = get_Cref(k, y0, tout - tout[0]).reshape((nt, 1, n))

    if verbose:
        print('rate: ', k)
        print(info)

    if plot:
        nshow = min(n, 3)
        try:
            min_atol = min(info['atol'])
        except:
            min_atol = info['atol']

        import matplotlib.pyplot as plt
        plt.figure(figsize=(6, 10))
        c = 'rgb'
        for i, l in enumerate('ABC'[:nshow]):
            ax = plt.subplot(nshow+1, 1, 1)
            if plotlogy:
                ax.set_yscale('log')
            if plotlogt:
                ax.set_xscale('log')
            ax.plot(tout, Cout[:, 0, i], label=l, color=c[i])

            ax = plt.subplot(nshow+1, 1, 2+i)
            if plotlogy:
                ax.set_yscale('symlog')  # abs error might be < 0
            if plotlogt:
                ax.set_xscale('log')
            ax.plot(tout, (Cout[:, 0, i]-Cref[:, 0, i])/min_atol,
                    label=l, color=c[i])

            try:
                atol = info['atol'][i]
            except:
                atol = info['atol']

            try:
                rtol = info['rtol'][i]
            except:
                rtol = info['rtol']

            le_l, le_u = solver_linear_error(
                yout[:, 0, i], rtol, atol, rd.logy, scale_err=scale_err, expb=rd.expb)
            plt.fill_between(tout, (le_l - Cout[:, 0, i])/min_atol,
                             (le_u - Cout[:, 0, i])/min_atol,
                             color=c[i], alpha=0.2)

            # Print indices and values of violations of (scaled) error bounds
            def _print(violation):
                print(violation)
                print(le_l[violation],
                      Cref[violation, 0, i],
                      le_u[violation])
            l_viols = np.where(le_l > Cref[:, 0, i])[0]
            u_viols = np.where(le_u < Cref[:, 0, i])[0]
            if verbose and (len(l_viols) > 0 or len(u_viols) > 0):
                print("Outside error bounds for rtol, atol:", rtol, atol)
                # for violation in chain(l_viols, u_viols):
                #     _print(violation)

        plt.subplot(nshow+1, 1, 1)
        plt.title('Concentration vs. time')
        plt.legend(loc='best', prop={'size': 11})
        plt.xlabel('t')
        plt.ylabel('[X]')
        for i in range(nshow):
            plt.subplot(nshow+1, 1, 2+i)
            plt.title('Absolute error in [{}](t) / min(atol)'.format('ABC'[i]))
            plt.legend(loc='best')
            plt.xlabel('t')
            plt.ylabel('|E[{0}]| / {1:7.0g}'.format('ABC'[i], min_atol))
        plt.tight_layout()
        save_and_or_show_plot(savefig=savefig)

    return integr.yout, Cref, rd, info
Example #23
0
def integrate_rd(tend=10.0, N=1, nt=500, jac_spy=False,
                 linear_solver='default', logy=False, logt=False,
                 plot=False, savefig='None', verbose=False, graph=False,
                 **kwargs):
    """
    Integrates the reaction system defined by
    :download:`four_species.json <examples/four_species.json>`
    """
    rd = load(os.path.join(os.path.dirname(
        __file__), 'four_species.json'), N=N, x=N, logy=logy, logt=logt)

    y0 = np.array([1.3, 1e-4, 0.7, 1e-4])
    y0 = np.concatenate([y0/(i+1)*(0.25*i**2+1) for i in range(N)])
    t0 = 1e-10

    if linear_solver == 'default':
        if rd.N == 1:
            linear_solver = 'dense'
        elif rd.N > 1:
            linear_solver = 'banded'
    if linear_solver not in ('dense', 'banded'):
        raise NotImplementedError("dense or banded linear_solver")

    import matplotlib.pyplot as plt
    if jac_spy:
        fout = np.empty(rd.n*rd.N)
        rd.f(t0, y0, fout)
        print(fout)
        if linear_solver == 'dense':
            jout = np.zeros((rd.n*rd.N, rd.n*rd.N), order='F')
            rd.dense_jac_cmaj(t0, y0, jout)
            coloured_spy(np.log(np.abs(jout)))
        elif linear_solver == 'banded':
            # note rd.n*3 needed in call from scipy.integrate.ode
            jout = np.zeros((rd.n*2+1, rd.n*rd.N), order='F')
            rd.banded_packed_jac_cmaj(t0, y0, jout)
            coloured_spy(np.log(np.abs(jout)))
        print(jout)
        plt.show()
    else:
        tout = np.linspace(t0, tend, nt)
        integr = run(rd, y0, tout, **kwargs)
        if verbose:
            print(integr.info)
        if plot:
            plt.figure(figsize=(6, 4))
            for i, l in enumerate('ABCD'):
                plt.plot(integr.tout, integr.Cout[:, 0, i], label=l)
            plt.title("Time evolution of concentrations")
            plt.legend()
            save_and_or_show_plot(savefig=savefig)

            plt.figure(figsize=(6, 10))
            plot_jacobian(
                rd,
                np.log(integr.tout) if rd.logt else integr.tout,
                np.log(integr.Cout) if rd.logy else integr.Cout,
                'ABCD',
                lintreshy=1e-10
            )
            plt.tight_layout()
            if savefig != 'None':
                base, ext = os.path.splitext(savefig)
                savefig = base + '_jacobian' + ext
            save_and_or_show_plot(savefig=savefig)

            plt.figure(figsize=(6, 10))
            plot_per_reaction_contribution(
                integr,
                'ABCD'
            )
            plt.tight_layout()
            if savefig != 'None':
                savefig = base + '_per_reaction' + ext
            save_and_or_show_plot(savefig=savefig)
    if graph:
        print(rsys2graph(ReactionSystem.from_ReactionDiffusion(rd, 'ABCD'),
                         'four_species_graph.png', save='.'))
    return integr
Example #24
0
def integrate_rd(tend=1e2, A0=1.0, B0=0.0, C0=0.0, k1=0.04, k2=1e4, k3=3e7,
                 t0=1e2, nt=100, N=1, nstencil=3, logt=False, logy=False,
                 plot=False, savefig='None', verbose=False, dump_expr='False',
                 use_chempy=False, D=2e-3):
    if N == 1:
        init_conc = (A0, B0, C0)
    else:
        init_conc = np.tile((A0, B0, C0), (N, 1))
        init_conc /= np.linspace(1, 2, N).reshape((N, 1))**.5

    rsys = ReactionSystem(get_reactions((k1, k2, k3)), 'ABC')
    if verbose:
        print([str(_) for _ in rsys.rxns])
    if use_chempy:
        from chempy.kinetics.ode import get_odesys
        odesys = get_odesys(rsys, include_params=True)
        if N != 1:
            raise ValueError("ChemPy does not support diffusion")
        odesys.integrate(np.logspace(log10(t0), log10(tend)), init_conc)
        if plot:
            odesys.plot_result(xscale='log', yscale='log')
        result = None
    else:
        rd = ReactionDiffusion.from_ReactionSystem(
            rsys, N=N, nstencil=1 if N == 1 else nstencil, logt=logt,
            logy=logy, D=[D/2, D/3, D/5])

        if dump_expr.lower() not in ('false', '0'):
            from chemreac.symbolic import SymRD
            import sympy as sp
            cb = {'latex': sp.latex,
                  'ccode': sp.ccode}.get(dump_expr.lower(), str)
            srd = SymRD.from_rd(rd, k=sp.symbols('k:3'))
            print('dydx:')
            print('\n'.join(map(cb, srd._f)))
            print('jac:')
            for ri, row in enumerate(srd.jacobian.tolist()):
                for ci, expr in enumerate(row):
                    if expr == 0:
                        continue
                    print(ri, ci, cb(expr))
            return None

        if t0 == 0 and logt:
            t0 = 1e-3*suggest_t0(rd, init_conc)
            if verbose:
                print("Using t0 = %12.5g" % t0)

        t = np.logspace(np.log10(t0), np.log10(tend), nt)
        print(t[0], t[-1])
        integr = run(rd, init_conc, t)

        if verbose:
            import pprint
            pprint.pprint(integr.info)

        if plot:
            if N == 1:
                plot_C_vs_t(integr, xscale='log', yscale='log')
            else:
                import matplotlib.pyplot as plt
                for idx, name in enumerate('ABC', 1):
                    plt.subplot(1, 3, idx)
                    rgb = [.5, .5, .5]
                    rgb[idx-1] = 1
                    plot_faded_time(integr, name, rgb=rgb, log_color=True)
        result = integr

    if plot:
        save_and_or_show_plot(savefig=savefig)

    return result
Example #25
0
def integrate_rd(D=2e-3, t0=3., tend=7., x0=0.0, xend=1.0, mu=None, N=32,
                 nt=25, geom='f', logt=False, logy=False, logx=False,
                 random=False, nstencil=3, lrefl=False, rrefl=False,
                 num_jacobian=False, method='bdf', plot=False,
                 atol=1e-6, rtol=1e-6, efield=False, random_seed=42,
                 verbose=False, use_log2=False):
    if random_seed:
        np.random.seed(random_seed)
    n = 1
    mu = float(mu or x0)
    tout = np.linspace(t0, tend, nt)

    assert geom in 'fcs'

    # Setup the grid
    logb = (lambda arg: log(arg)/log(2)) if use_log2 else log

    _x0 = logb(x0) if logx else x0
    _xend = logb(xend) if logx else xend
    x = np.linspace(_x0, _xend, N+1)
    if random:
        x += (np.random.random(N+1)-0.5)*(_xend-_x0)/(N+2)

    mob = 0.3
    # Initial conditions
    y0 = {
        'f': y0_flat_cb,
        'c': y0_cylindrical_cb,
        's': y0_spherical_cb
    }[geom](x, logx)

    # Setup the system
    stoich_active = []
    stoich_prod = []
    k = []

    assert not lrefl
    assert not rrefl

    rd = ReactionDiffusion(
        n, stoich_active, stoich_prod, k, N,
        D=[D],
        z_chg=[1],
        mobility=[mob],
        x=x,
        geom=geom,
        logy=logy,
        logt=logt,
        logx=logx,
        nstencil=nstencil,
        lrefl=lrefl,
        rrefl=rrefl,
        use_log2=use_log2
    )

    if efield:
        if geom != 'f':
            raise ValueError("Only analytic sol. for flat drift implemented.")
        rd.efield = efield_cb(rd.xcenters, logx)

    # Analytic reference values
    t = tout.copy().reshape((nt, 1))
    Cref = np.repeat(y0[np.newaxis, :, np.newaxis], nt, axis=0)
    if efield:
        Cref += t.reshape((nt, 1, 1))*mob

    # Run the integration
    integr = run(rd, y0, tout, atol=atol, rtol=rtol,
                 with_jacobian=(not num_jacobian), method=method)
    Cout, info = integr.Cout, integr.info

    if verbose:
        print(info)

    def lin_err(i=slice(None), j=slice(None)):
        return integr.Cout[i, :, j] - Cref[i, :, j]

    rmsd = np.sum(lin_err()**2 / N, axis=1)**0.5
    ave_rmsd_over_atol = np.average(rmsd, axis=0)/info['atol']

    # Plot results
    if plot:
        import matplotlib.pyplot as plt

        def _plot(y, c, ttl=None, apply_exp_on_y=False):
            plt.plot(rd.xcenters, rd.expb(y) if apply_exp_on_y else y, c=c)
            if N < 100:
                plt.vlines(rd.x, 0, np.ones_like(rd.x)*max(y), linewidth=.1,
                           colors='gray')
            plt.xlabel('x / m')
            plt.ylabel('C / M')
            if ttl:
                plt.title(ttl)

        for i in range(nt):
            c = 1-tout[i]/tend
            c = (1.0-c, .5-c/2, .5-c/2)  # over time: dark red -> light red

            plt.subplot(4, 1, 1)
            _plot(Cout[i, :, 0], c, 'Simulation (N={})'.format(rd.N),
                  apply_exp_on_y=logy)

            plt.subplot(4, 1, 2)
            _plot(Cref[i, :, 0], c, 'Analytic', apply_exp_on_y=logy)

            ax_err = plt.subplot(4, 1, 3)
            plot_solver_linear_error(integr, Cref, ax_err, ti=i,
                                     bi=slice(None),
                                     color=c, fill=(i == 0))
            plt.title('Linear rel error / Log abs. tol. (={})'.format(
                      info['atol']))

        plt.subplot(4, 1, 4)
        tspan = [tout[0], tout[-1]]
        plt.plot(tout, rmsd[:, 0] / info['atol'], 'r')
        plt.plot(tspan, [ave_rmsd_over_atol[0]]*2, 'r--')

        plt.xlabel('Time / s')
        plt.ylabel(r'$\sqrt{\langle E^2 \rangle} / atol$')
        plt.tight_layout()
        plt.show()
    return tout, Cout, info, ave_rmsd_over_atol, rd
Example #26
0
def integrate_rd(tend=1.0, k1=7e-1, k2=3e2, k3=7.0,
                 A0=1.0, B0=0.0, C0=0.0, nt=512,
                 plot=False, savefig='None'):
    """
    Runs integration and (optionally) generates plots.


    Examples
    --------
    ::

       $ python steady_state_approx.py --plot --savefig steady_state_approx.png


    .. image:: ../_generated/steady_state_approx.png


    ::

       $ python steady_state_approx.py --plot --savefig \
steady_state_approx.html


    :download:`steady_state_approx.html\
        <../_generated/steady_state_approx.html>`

    """
    def f(t):
        return A0/(k3/k2*A0 + 1)*np.exp(-k1*t)

    y = [A0, B0, C0]
    k = [k1, k2, k3]
    rd = ReactionDiffusion(
        3, [[0], [1], [0, 1]], [[1], [2], [1, 2]], k)
    t = np.linspace(0, tend, nt)
    integr = run(rd, y, t)
    A_ssB = 1/(1/f(t) - k3/k2)
    A_ssB_2fast = f(t)

    if plot:
        import matplotlib.pyplot as plt
        plt.figure(figsize=(6, 10))

        ax = plt.subplot(3, 1, 1)
        plot_C_vs_t_in_bin(rd, t, integr.Cout, ax=ax)
        plt.subplot(3, 1, 2)
        plt.plot(t, integr.Cout[:, 0, 0] - A_ssB,
                 label="Abs. err. in A assuming steady state of B")
        plt.legend(loc='best', prop={'size': 11})
        plt.subplot(3, 1, 3)
        plt.plot(t, integr.Cout[:, 0, 0] - A_ssB_2fast,
                 label="Abs. err. in A when also assuming k2 >> k3")
        plt.legend(loc='best', prop={'size': 11})
        plt.tight_layout()

        save_and_or_show_plot(savefig=savefig)

    def ydot(x, y):
        return (-k1*y[0] - k3*y[0]*y[1], k1*y[0] - k2*y[1],
                k2*y[1] + k3*y[0]*y[1])
    return t, integr.Cout, A_ssB, A_ssB_2fast, ydot