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))
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)