def test_n_jac_diags(n_jac_diags): N, n, nstencil = 10, 1, 7 rd = ReactionDiffusion(n, [], [], [], N=N, nstencil=nstencil, n_jac_diags=n_jac_diags, D=[9]) assert np.allclose(rd.xcenters, [.05, .15, .25, .35, .45, .55, .65, .75, .85, .95]) y0 = np.ones(N) # Dense jref_cdns = np.zeros((n*N, n*N), order='F') jout_cdns = np.zeros((n*N, n*N), order='F') sm = SymRD.from_rd(rd) sm.dense_jac(0.0, y0.flatten(), jref_cdns) rd.dense_jac_cmaj(0.0, y0.flatten(), jout_cdns) assert np.allclose(jout_cdns, jref_cdns) # Banded jref_cbnd = rd.alloc_jout(order='F', pad=0) jout_cbnd = rd.alloc_jout(order='F') sm.banded_jac(0.0, y0.flatten(), jref_cbnd) rd.banded_jac_cmaj(0.0, y0.flatten(), jout_cbnd) assert np.allclose(jout_cbnd[rd.n*rd.n_jac_diags:, :], jref_cbnd) # Compressed jref_cmprs = rd.alloc_jout_compressed() jout_cmprs = rd.alloc_jout_compressed() sm.compressed_jac(0.0, y0.flatten(), jref_cmprs) rd.compressed_jac_cmaj(0.0, y0.flatten(), jout_cmprs) assert np.allclose(jout_cmprs, jref_cmprs)
def test_ReactionDiffusion__only_1_species_diffusion_7bins(log): # Diffusion without reaction N = 7 nstencil = 5 nsidep = (nstencil-1)//2 t0 = 3.0 logy, logt = log D = 2.0 y0 = np.array([12, 8, 11, 5, 7, 4, 9], dtype=np.float64) x = np.array([3, 5, 13, 17, 23, 25, 35, 37], dtype=np.float64) rd = ReactionDiffusion(1, [], [], [], D=[D], x=x, logy=logy, logt=logt, nstencil=nstencil, lrefl=False, rrefl=False) weights = [ [951/8800, -716/2475, 100/297, -75/352, 311/5400], [321/8800, -161/2475, 7/297, 3/352, -19/5400], [-39/8800, 109/2475, -127/1485, 87/1760, -19/5400], [-2/693, 38/675, -129/1100, 7/108, -1/1050], [0, 9/160, -7/72, 2/45, -1/288], [-8/1575, 9/400, 0, -19/450, 25/1008], [16/315, -9/32, 31/72, -13/45, 179/2016] ] assert np.allclose(rd.D_weight, np.array(weights).flatten()) lb = stencil_pxci_lbounds(nstencil, N) yi = pxci_to_bi(nstencil, N) fref = np.array([sum([D*weights[i][j]*y0[yi[j+lb[i]]] for j in range(nstencil)]) for i in range(N)]) if logy: fref /= y0 if logt: fref *= t0 jref = np.zeros((N, N)) for i in range(N): for j in range(max(0, i-1), min(N, i+2)): if logy: if j == i+1 or j == i-1: for k in range(nstencil): if yi[k+lb[i]] == j: jref[i, j] += D*weights[i][k]*y0[j]/y0[i] else: # j == i assert i == j for k in range(nstencil): cyi = yi[k+lb[i]] if i == cyi: continue jref[i, i] -= D*weights[i][k]*y0[cyi]/y0[i] else: if i-1 <= j and j <= i+1: jref[i, j] = D*weights[i][j-lb[i]+nsidep] if logt: jref *= t0 t = rd.logb(t0) if logt else t0 y = rd.logb(y0) if logy else y0 _test_f_and_dense_jac_rmaj(rd, t, y, fref, jref) jout_bnd = np.zeros((4, N), order='F') rd.banded_jac_cmaj(t, y, jout_bnd) jref_bnd = get_banded(jref, 1, N) assert np.allclose(jout_bnd[1:, :], jref_bnd) # compressed_jac_cmaj actually use all diagonals rd = ReactionDiffusion(1, [], [], [], D=[D], x=x, logy=logy, logt=logt, nstencil=nstencil, lrefl=False, rrefl=False, n_jac_diags=2) jout_cmprs = rd.alloc_jout_compressed() rd.compressed_jac_cmaj(t, y, jout_cmprs) from block_diag_ilu import Compressed_from_dense jref2 = np.zeros((N, N)) for i in range(N): for j in range(max(0, i-2), min(N, i+3)): if logy: if i-2 <= j <= i+2: if i == j: for k in range(nstencil): cyi = yi[k+lb[i]] if i == cyi: continue jref2[i, i] -= D*weights[i][k]*y0[cyi]/y0[i] else: for k in range(nstencil): if yi[k+lb[i]] == j: jref2[i, j] += D*weights[i][k]*y0[j]/y0[i] else: if i-2 <= j <= i+2: jref2[i, j] = D*weights[i][j-lb[i]+nsidep] if logt: jref2 *= t0 jref_cmprs = Compressed_from_dense(jref2, N, 1, nsidep).data assert np.allclose(jout_cmprs, jref_cmprs)