Exemplo n.º 1
0
def test_padded_centers():
    b = [0, 2, 6]
    xc_ = padded_centers(b, 1)
    assert np.allclose(xc_, [-1, 1, 4, 8])

    b = np.arange(10, 21)
    xc_ = padded_centers(b, 2)
    print(xc_)
    assert np.allclose(xc_, np.linspace(8.5, 21.5, 14))
Exemplo n.º 2
0
def test_ReactionDiffusion__lrefl_7(log):
    # Diffusion without reaction (7 bins)
    from sympy import finite_diff_weights
    lrefl, rrefl = True, False
    N = 7
    t0 = 3.0
    logy, logt = log
    D = 17.0
    nstencil = 5
    nsidep = (nstencil-1)//2
    x = np.array([3, 5, 13, 17, 23, 25, 35, 37], dtype=np.float64)
    y0 = np.array([12, 8, 11, 5, 7, 4, 9], dtype=np.float64)
    xc_ = padded_centers(x, nsidep)
    lb = stencil_pxci_lbounds(nstencil, N, lrefl=lrefl, rrefl=rrefl)

    rd = ReactionDiffusion(1, [], [], [], D=[D], x=x, logy=logy,
                           logt=logt, N=N, nstencil=nstencil,
                           lrefl=lrefl, rrefl=rrefl)

    y = rd.logb(y0) if logy else y0
    t = rd.logb(t0) if logt else t0
    le = nsidep if lrefl else 0
    D_weight_ref = np.array([
        finite_diff_weights(
            2, xc_[lb[i]:lb[i]+nstencil], x0=xc_[le+i])[-1][-1]
        for i in range(N)], dtype=np.float64)
    assert np.allclose(rd.D_weight, D_weight_ref.flatten())

    yi = pxci_to_bi(nstencil, N)

    fref = D*np.array([
        sum([rd.D_weight[i*nstencil+j]*y0[yi[lb[i]+j]]
             for j in range(nstencil)])
        for i in range(N)
    ])

    if logy:
        fref /= y0
    if logt:
        fref *= t0

    _test_f(rd, t, y, fref)

    if logy:
        def cb(i, j):
            if abs(i-j) > 1:
                return 0  # imperfect Jacobian
            elif i == j:
                res = 0
                for k in range(nstencil):
                    cyi = yi[lb[i] + k]  # current y index
                    if cyi != i:
                        res -= y0[cyi]/y0[i]*rd.D_weight[i*nstencil + k]
                return res
            else:
                res = 0
                for k in range(nstencil):
                    cyi = yi[lb[i] + k]  # current y index
                    if cyi == j:
                        res += y0[j]/y0[i]*rd.D_weight[i*nstencil + k]
                return res
    else:
        def cb(i, j):
            if abs(i-j) > 1:
                return 0  # imperfect Jacobian
            res = 0
            for k in range(nstencil):
                if yi[lb[i]+k] == j:
                    res += rd.D_weight[i*nstencil + k]
            return res
    jref = D*np.array([cb(i, j) for i, j in product(
        range(N), range(N))]).reshape(N, N)
    if logt:
        jref *= t0

    _test_dense_jac_rmaj(rd, t, y, jref)