Exemple #1
0
def jacres_T(U, Uold, peq, neq, sepq, accq, zccq):
    Mp = peq.M
    Mn = neq.M
    Ms = sepq.M
    Ma = accq.M
    Mz = zccq.M
    Np = peq.N
    Nn = neq.N

    cmat_pe, cmat_ne, \
    uvec_pe, uvec_sep, uvec_ne,\
    Tvec_acc, Tvec_pe, Tvec_sep, Tvec_ne, Tvec_zcc, \
    phie_pe, phie_sep, phie_ne, phis_pe, phis_ne, \
    j_pe,j_ne,eta_pe,eta_ne = unpack(U, Mp, Np, Mn, Nn, Ms, Ma, Mz)

    cmat_old_pe, cmat_old_ne,\
    uvec_old_pe, uvec_old_sep, uvec_old_ne,\
    Tvec_old_acc, Tvec_old_pe, Tvec_old_sep, Tvec_old_ne, Tvec_old_zcc,\
    _, _, \
    _, _,\
    _,_,\
    _,_,_= unpack(Uold,Mp, Np, Mn, Nn, Ms, Ma, Mz)
    """ Current Collector a residual """

    bc_T0a = accq.bc_temp_a(Tvec_acc[0], Tvec_acc[1])
    res_Ta = vmap(accq.temperature)(Tvec_acc[0:Ma], Tvec_acc[1:Ma + 1],
                                    Tvec_acc[2:Ma + 2], Tvec_old_acc[1:Ma + 1])
    bc_TMa = peq.bc_temp_ap(Tvec_acc[Ma], Tvec_acc[Ma + 1], Tvec_pe[0],
                            Tvec_pe[1])
    """ jacobian"""
    bc_T0a_grad = grad(accq.bc_temp_a, (0, 1))(Tvec_acc[0], Tvec_acc[1])
    A_Ta = vmap(grad(accq.temperature,
                     range(0, 3)))(Tvec_acc[0:Ma], Tvec_acc[1:Ma + 1],
                                   Tvec_acc[2:Ma + 2], Tvec_old_acc[1:Ma + 1])
    bc_TMa_grad = grad(peq.bc_temp_ap,
                       range(0, 4))(Tvec_acc[Ma], Tvec_acc[Ma + 1], Tvec_pe[0],
                                    Tvec_pe[1])

    bcTa = {"right": bc_T0a_grad[0:2], "left": bc_TMa_grad[0:2]}
    J_TTaa = build_tridiag(Ma, A_Ta[0:3], **bcTa)
    J_TTap = coo_matrix(
        (np.ravel(np.asarray(bc_TMa_grad[2:4])), ([Ma + 1, Ma + 1], [0, 1])),
        shape=(Ma + 2, Mp + 2 + Ms + 2 + Mn + 2 + Mz + 2))
    J_TTa = hstack([J_TTaa, J_TTap])
    """ Positive electrode residual """
    arg_T0p = [Tvec_acc[Ma], Tvec_acc[Ma + 1], Tvec_pe[0], Tvec_pe[1]]
    #arg_T = [uvec_pe[0:Mp], uvec_pe[1:Mp+1], uvec_pe[2:Mp+2], pe.phievec[0:Mp],pe.phievec[2:Mp+2],\
    #         phis_pe[0:Mp], phis_pe[2:Mp+2], Tvec_pe[0:Mp], Tvec_pe[1:Mp+1], Tvec_pe[2:Mp+2], j_pe[0:Mp],\
    #         eta_pe[0:Mp], pe.cs[0:Mp], pe.cmax*np.ones([Mp,1]), Tvec_old_pe[1:Mp+1]]
    arg_Tp = [uvec_pe[0:Mp], uvec_pe[1:Mp+1], uvec_pe[2:Mp+2],
              phie_pe[0:Mp],phie_pe[2:Mp+2],\
             phis_pe[0:Mp], phis_pe[2:Mp+2],
             Tvec_pe[0:Mp], Tvec_pe[1:Mp+1], Tvec_pe[2:Mp+2],
             j_pe[0:Mp],\
             eta_pe[0:Mp],
             cmat_pe[Np,:], cmat_pe[Np+1,:],peq.cmax*np.ones([Mp,1]),
             Tvec_old_pe[1:Mp+1]]
    arg_TMp = [Tvec_pe[Mp], Tvec_pe[Mp + 1], Tvec_sep[0], Tvec_sep[1]]

    bc_T0p = peq.bc_inter_cont(*arg_T0p)
    res_Tp = vmap(peq.temperature)(*arg_Tp)
    bc_TMp = peq.bc_temp_ps(*arg_TMp)

    A_Tp = vmap(grad(peq.temperature, range(0, len(arg_Tp) - 2)))(*arg_Tp)
    bc_T0p_grad = grad(peq.bc_inter_cont, range(0, len(arg_T0p)))(*arg_T0p)
    bc_TMp_grad = grad(peq.bc_temp_ps, range(0, 4))(*arg_TMp)

    bcTp = {"right": bc_T0p_grad[2:4], "left": bc_TMp_grad[0:2]}
    J_TTpp = build_tridiag(Mp, A_Tp[7:10], **bcTp)
    J_TTpa = coo_matrix(
        (np.ravel(np.asarray(bc_T0p_grad[0:2])), ([0, 0], [Ma, Ma + 1])),
        shape=(Mp + 2, Ma + 2))
    J_TTps = coo_matrix(
        (np.ravel(np.asarray(bc_TMp_grad[2:4])), ([Mp + 1, Mp + 1], [0, 1])),
        shape=(Mp + 2, Ms + 2 + Mn + 2 + Mz + 2))
    J_TTp = hstack([J_TTpa, J_TTpp, J_TTps])

    J_Tup = build_tridiag(Mp, A_Tp[0:3])
    J_Tphiep = build_bidiag(Mp, A_Tp[3:5])
    J_Tphisp = build_bidiag(Mp, A_Tp[5:7])
    J_Tjp = build_diag(Mp, A_Tp[10], "long")
    J_Tetap = build_diag(Mp, A_Tp[11], "long")

    col_cp = []
    data_cp = []
    row_cp = np.repeat(Ma + 2 + np.arange(1, Mp + 1), 2)
    for i in range(0, Mp):
        col_cp.append([Np + (Np + 2) * i, Np + 1 + (Np + 2) * (i)])
        data_cp.append([A_Tp[12][i], A_Tp[13][i]])
    data_cp = np.ravel(np.array(data_cp))
    col_cp = np.ravel(np.array(col_cp))
    J_cp = coo_matrix((data_cp, (row_cp, col_cp)),
                      shape=(Ma + 2 + Mp + 2, Mp * (Np + 2) + Mn * (Nn + 2)))
    """ Separator residual """

    arg_T0s = [Tvec_pe[Mp], Tvec_pe[Mp + 1], Tvec_sep[0], Tvec_sep[1]]
    arg_Ts = [uvec_sep[0:Ms], uvec_sep[1:Ms+1], uvec_sep[2:Ms+2], phie_sep[0:Ms], phie_sep[2:Ms+2],\
              Tvec_sep[0:Ms], Tvec_sep[1:Ms+1], Tvec_sep[2:Ms+2], Tvec_old_sep[1:Ms+1]]
    arg_TMs = [Tvec_sep[Ms], Tvec_sep[Ms + 1], Tvec_ne[0], Tvec_ne[1]]

    bc_T0s = peq.bc_inter_cont(*arg_T0s)
    res_Ts = vmap(sepq.temperature)(*arg_Ts)
    bc_TMs = sepq.bc_temp_sn(*arg_TMs)

    bc_T0s_grad = grad(peq.bc_inter_cont, range(0, 4))(*arg_T0s)
    bc_TMs_grad = grad(sepq.bc_temp_sn, range(0, 4))(*arg_TMs)
    A_Ts = vmap(grad(sepq.temperature, range(0, len(arg_Ts) - 1)))(*arg_Ts)

    bcTs = {"right": bc_T0s_grad[2:4], "left": bc_TMs_grad[0:2]}
    J_TTss = build_tridiag(Ms, A_Ts[5:8], **bcTs)
    J_TTsp = coo_matrix((np.ravel(np.asarray(bc_T0s_grad[0:2])),
                         ([0, 0], [Ma + 2 + Mp, Ma + 2 + Mp + 1])),
                        shape=(Ms + 2, Ma + 2 + Mp + 2))
    J_TTsn = coo_matrix(
        (np.ravel(np.asarray(bc_TMs_grad[2:4])), ([Ms + 1, Ms + 1], [0, 1])),
        shape=(Ms + 2, Mn + 2 + Mz + 2))
    J_TTs = hstack([J_TTsp, J_TTss, J_TTsn])

    J_Tus = build_tridiag(Ms, A_Ts[0:3])
    J_Tphies = build_bidiag(Ms, A_Ts[3:5])
    """ Negative residual """
    arg_T0n = [Tvec_sep[Ms], Tvec_sep[Ms + 1], Tvec_ne[0], Tvec_ne[1]]
    arg_Tn = [uvec_ne[0:Mn], uvec_ne[1:Mn+1], uvec_ne[2:Mn+2], phie_ne[0:Mn],phie_ne[2:Mn+2],\
             phis_ne[0:Mn], phis_ne[2:Mn+2], Tvec_ne[0:Mn], Tvec_ne[1:Mn+1], Tvec_ne[2:Mn+2], j_ne[0:Mn],\
             eta_ne[0:Mn], cmat_ne[Nn,:], cmat_ne[Nn+1,:], neq.cmax*np.ones([Mn,1]), Tvec_old_ne[1:Mn+1]]
    arg_TMn = [Tvec_ne[Mn], Tvec_ne[Mn + 1], Tvec_zcc[0], Tvec_zcc[1]]

    bc_T0n = neq.bc_inter_cont(*arg_T0n)
    res_Tn = vmap(neq.temperature)(*arg_Tn)
    bc_TMn = neq.bc_temp_n(*arg_TMn)
    """jacobian"""
    A_Tn = vmap(grad(neq.temperature, range(0, len(arg_Tn) - 2)))(*arg_Tn)
    bc_T0n_grad = grad(neq.bc_inter_cont, range(0, 4))(*arg_T0n)
    bc_TMn_grad = grad(neq.bc_temp_n, range(0, 4))(*arg_TMn)

    bcTn = {"right": bc_T0n_grad[2:4], "left": bc_TMn_grad[0:2]}
    J_TTnn = build_tridiag(Mn, A_Tn[7:10], **bcTn)
    J_TTns = coo_matrix(
        (np.ravel(np.asarray(bc_T0n_grad[0:2])),
         ([0, 0], [Ma + 2 + Mp + 2 + Ms, Ma + 2 + Mp + 2 + Ms + 1])),
        shape=(Mn + 2, Ma + 2 + Mp + 2 + Ms + 2))
    J_TTnz = coo_matrix(
        (np.ravel(np.asarray(bc_TMn_grad[2:4])), ([Mn + 1, Mn + 1], [0, 1])),
        shape=(Mn + 2, Mz + 2))
    J_TTn = hstack([J_TTns, J_TTnn, J_TTnz])

    J_Tun = build_tridiag(Mn, A_Tn[0:3])
    J_Tphien = build_bidiag(Mn, A_Tn[3:5])
    J_Tphisn = build_bidiag(Mn, A_Tn[5:7])
    J_Tjn = build_diag(Mn, A_Tn[10], "long")
    J_Tetan = build_diag(Mn, A_Tn[11], "long")

    col_cn = []
    data_cn = []
    row_cn = np.repeat(np.arange(1, Mn + 1), 2)
    offset = Mp * (Np + 2)
    for i in range(0, Mn):
        col_cn.append(
            [Nn + (Nn + 2) * i + offset, Nn + 1 + (Nn + 2) * (i) + offset])
        data_cn.append([A_Tn[12][i], A_Tn[13][i]])
    data_cn = np.ravel(np.array(data_cn))
    col_cn = np.ravel(np.array(col_cn))
    J_cn = coo_matrix((data_cn, (row_cn, col_cn)),
                      shape=(Mz + 2 + Mn + 2, Mn * (Nn + 2) + offset))
    """ Current collector z residual """
    arg_T0z = [Tvec_ne[Mn], Tvec_ne[Mn + 1], Tvec_zcc[0], Tvec_zcc[1]]
    arg_Tz = [
        Tvec_zcc[0:Mz], Tvec_zcc[1:Mz + 1], Tvec_zcc[2:Mz + 2],
        Tvec_old_zcc[1:Mz + 1]
    ]
    arg_TMz = [Tvec_zcc[Mz], Tvec_zcc[Mz + 1]]

    bc_T0z = neq.bc_inter_cont(*arg_T0z)
    res_Tz = vmap(zccq.temperature)(*arg_Tz)
    bc_TMz = zccq.bc_temp_z(*arg_TMz)
    """ jacobian"""
    bc_T0z_grad = grad(neq.bc_inter_cont, range(0, 4))(*arg_T0z)
    A_Tz = vmap(grad(zccq.temperature, range(0, 3)))(*arg_Tz)
    bc_TMz_grad = grad(zccq.bc_temp_z, (0, 1))(*arg_TMz)

    bcTz = {"right": bc_T0z_grad[2:4], "left": bc_TMz_grad[0:2]}
    J_TTzz = build_tridiag(Mz, A_Tz[0:3], **bcTz)
    J_TTzn = coo_matrix(
        (np.ravel(np.asarray(bc_T0z_grad[0:2])),
         ([0, 0],
          [Ma + 2 + Mp + 2 + Ms + 2 + Mn, Ma + 2 + Mp + 2 + Ms + 2 + Mn + 1])),
        shape=(Mz + 2, Ma + 2 + Mp + 2 + Ms + 2 + Mn + 2))

    J_TTz = hstack([J_TTzn, J_TTzz])


    J_Tu = bmat([ [empty_rec(Ma+2, (Mp+2)+(Ms+2)+(Mn+2))],\
                   [block_diag((J_Tup, J_Tus, J_Tun))],\
                   [empty_rec(Mz+2, (Mp+2) + (Ms+2) + (Mn+2))]
                   ])
    J_Tphie = bmat([ [empty_rec(Ma+2, (Mp+2)+(Ms+2)+(Mn+2))],\
                   [block_diag((J_Tphiep, J_Tphies, J_Tphien))],\
                   [empty_rec(Mz+2, (Mp+2) + (Ms+2) + (Mn+2))]
                   ])
    J_Tphis = vstack([
        empty_rec(Ma + 2, (Mp + 2) + (Mn + 2)),
        hstack([J_Tphisp, empty_rec(Mp + 2, Mn + 2)]),
        empty_rec(Ms + 2, (Mp + 2) + (Mn + 2)),
        hstack([empty_rec(Mn + 2, Mp + 2), J_Tphisn]),
        empty_rec(Mz + 2, (Mp + 2) + (Mn + 2))
    ])

    J_Tj = vstack([
        empty_rec(Ma + 2, Mp + Mn),
        hstack([J_Tjp, empty_rec(Mp + 2, Mn)]),
        empty_rec(Ms + 2, Mp + Mn),
        hstack([empty_rec(Mn + 2, Mp), J_Tjn]),
        empty_rec(Mz + 2, Mp + Mn)
    ])

    J_Teta = vstack([
        empty_rec(Ma + 2, Mp + Mn),
        hstack([J_Tetap, empty_rec(Mp + 2, Mn)]),
        empty_rec(Ms + 2, Mp + Mn),
        hstack([empty_rec(Mn + 2, Mp), J_Tetan]),
        empty_rec(Mz + 2, Mp + Mn)
    ])

    J_TT = vstack([J_TTa, J_TTp, J_TTs, J_TTn, J_TTz])

    J_Tc = vstack(
        [J_cp, empty_rec(Ms + 2,
                         Mp * (Np + 2) + Mn * (Nn + 2)), J_cn])

    res_T = np.hstack(
        (bc_T0a, res_Ta, bc_TMa, bc_T0p, res_Tp, bc_TMp, bc_T0s, res_Ts,
         bc_TMs, bc_T0n, res_Tn, bc_TMn, bc_T0z, res_Tz, bc_TMz))

    J_T = hstack([J_Tc, J_Tu, J_TT, J_Tphie, J_Tphis, J_Tj, J_Teta])

    return res_T, J_T


#plt.figure(figsize=(20,10)); plt.spy(J_T, markersize=1);plt.savefig('Tsparsity.png')
Exemple #2
0
def jacres_j(acc, pe, sep, ne, zcc):
    Mp = peq.M
    Mn = neq.M
    Ms = sepq.M
    Ma = accq.M
    Mz = zccq.M
    Np = peq.N
    Nn = neq.N

    arg_jp = [
        pe.jvec[0:Mp], pe.uvec[1:Mp + 1], pe.Tvec[1:Mp + 1], pe.etavec[0:Mp],
        pe.cmat[Np, :], pe.cmat[Np + 1, :], pe.cmax * np.ones([Mp, 1])
    ]
    res_jp = vmap(peq.ionic_flux)(*arg_jp)
    A_jp = vmap((grad(peq.ionic_flux, range(0, len(arg_jp) - 1))))(*arg_jp)

    J_jp = build_diag(Mp, A_jp[0], "square")
    J_jup = build_diag(Mp, A_jp[1], "wide")
    J_jTp = build_diag(Mp, A_jp[2], "wide")
    J_jetap = build_diag(Mp, A_jp[3], "square")

    col_cp = []
    data_cp = []
    #    row_cp = np.repeat( np.arange(0,Mp), 2)
    row_cp = np.repeat(np.arange(0, Mp), 2)
    for i in range(0, Mp):
        #        col_cp.append([Np + (Np+2)*(i), Np+1 + (Np+2)*(i) ])
        #        data_cp.append([A_jp[4][i], A_jp[5][i]])
        col_cp.append([Np + (Np + 2) * i, Np + 1 + (Np + 2) * (i)])
        data_cp.append([A_jp[4][i], A_jp[5][i]])
    data_cp = np.ravel(np.array(data_cp))
    col_cp = np.ravel(np.array(col_cp))
    J_cp = coo_matrix((data_cp, (row_cp, col_cp)),
                      shape=(Mp, Mp * (Np + 2) + Mn * (Nn + 2)))
    """ Negative Electrode"""

    arg_jn = [
        ne.jvec[0:Mn], ne.uvec[1:Mn + 1], ne.Tvec[1:Mn + 1], ne.etavec[0:Mn],
        ne.cmat[Nn, :], ne.cmat[Nn + 1, :], ne.cmax * np.ones([Mn, 1])
    ]
    res_jn = vmap(neq.ionic_flux)(*arg_jn)
    A_jn = vmap((grad(neq.ionic_flux, range(0, len(arg_jn) - 1))))(*arg_jn)

    J_jn = build_diag(Mn, A_jn[0], "square")
    J_jun = build_diag(Mn, A_jn[1], "wide")
    J_jTn = build_diag(Mn, A_jn[2], "wide")
    J_jetan = build_diag(Mn, A_jn[3], "square")

    col_cn = []
    data_cn = []
    offset = (Np + 2) * Mp
    row_cn = np.repeat(np.arange(0, Mn), 2)
    for i in range(0, Mn):
        col_cn.append(
            [Nn + (Nn + 2) * i + offset, Nn + 1 + (Nn + 2) * (i) + offset])
        data_cn.append([A_jn[4][i], A_jn[5][i]])
    data_cn = np.ravel(np.array(data_cn))
    col_cn = np.ravel(np.array(col_cn))
    J_cn = coo_matrix((data_cn, (row_cn, col_cn)),
                      shape=(Mn, Mp * (Np + 2) + Mn * (Nn + 2)))
    """" total """
    J_ju = hstack([
        vstack([J_jup, empty_rec(Mn, Mp + 2)]),
        empty_rec(Mp + Mn, Ms + 2),
        vstack([empty_rec(Mp, Mn + 2), J_jun])
    ])

    J_jT = hstack([
        empty_rec(Mp + Mn, Ma + 2),
        vstack([J_jTp, empty_rec(Mn, Mp + 2)]),
        empty_rec(Mp + Mn, Ms + 2),
        vstack([empty_rec(Mp, Mn + 2), J_jTn]),
        empty_rec(Mp + Mn, Mz + 2)
    ])

    J_jj = block_diag((J_jp, J_jn))

    J_jeta = block_diag((J_jetap, J_jetan))

    J_jc = vstack([J_cp, J_cn])

    res_j = np.hstack((res_jp, res_jn))
    J_j = hstack([
        J_jc, J_ju, J_jT,
        empty_rec(Mp + Mn, Mp + 2 + Ms + 2 + Mn + 2),
        empty_rec(Mp + Mn, Mp + 2 + Mn + 2), J_jj, J_jeta
    ])

    return res_j, J_j
Exemple #3
0
def jacres_c(U, Uold, peq, neq, sepq, accq, zccq):
    Mp = peq.M
    Mn = neq.M
    Ms = sepq.M
    Ma = accq.M
    Mz = zccq.M
    Np = peq.N
    Nn = neq.N

    cmat_pe, cmat_ne, \
    uvec_pe, uvec_sep, uvec_ne,\
    Tvec_acc, Tvec_pe, Tvec_sep, Tvec_ne, Tvec_zcc, \
    phie_pe, phie_sep, phie_ne, phis_pe, phis_ne, \
    j_pe,j_ne,eta_pe,eta_ne = unpack(U, Mp, Np, Mn, Nn, Ms, Ma, Mz)

    cmat_old_pe, cmat_old_ne,\
    uvec_old_pe, uvec_old_sep, uvec_old_ne,\
    Tvec_old_acc, Tvec_old_pe, Tvec_old_sep, Tvec_old_ne, Tvec_old_zcc,\
    _, _, \
    _, _,\
    _,_,\
    _,_,_= unpack(Uold,Mp, Np, Mn, Nn, Ms, Ma, Mz)
    """ Positive """
    k = delta_t
    Np = peq.N
    Rp = peq.Rp * (np.linspace(1, N, N) - (1 / 2)) / N
    rp = peq.Rp * (np.linspace(0, N, N + 1)) / N
    lambda1_p = k * r[0:N]**2 / (R**2 * hy**2)
    lambda2_p = k * r[1:N + 1]**2 / (R**2 * hy**2)

    res_cp = onp.zeros([(Np + 2) * Mp, 1])
    for i in range(0, Mp):
        arg_cp = [
            cmat_pe[0:Np, i], cmat_pe[1:Np + 1, i], cmat_pe[2:Np + 2, i],
            cmat_old_pe[1:Np + 1, i], lambda1_p, lambda2_p
        ]
        arg_c0p = [cmat_pe[0, i], cmat_pe[1, i]]
        arg_cMp = [cmat_pe[Np, i], cmat_pe[Np + 1, i], j_pe[i], Tvec_pe[i + 1]]

        res_cp[(i) * (Np + 2)] = peq.bc_zero_neumann(*arg_c0p)
        res_cp[i * (Np + 2) + 1:Np + 1 + i * (Np + 2)] = np.reshape(
            peq.solid_conc(*arg_cp), [Np, 1])
        #        res_cp[i*(Np+2)+1: Np + 1 + i*(Np+2)] = vmap(peq.solid_conc)(*arg_cp)
        res_cp[(Np + 1) + i * (Np + 2)] = peq.bc_neumann_c(*arg_cMp)

    res_cp = np.asarray(res_cp)
    """ Linear Jacobian """
    bc_cp0_grad = np.array([[-1, 1]]).T
    A_cp = vmap(grad(peq.solid_conc_2, range(0, 3)))(*arg_cp)
    bc_cpM_grad = np.array([[-1 / peq.hy, 1 / peq.hy]]).T

    bcp = {"right": bc_cp0_grad, "left": bc_cpM_grad}
    J_cp_sub = build_tridiag_c(Np, A_cp, **bcp)
    Ip = identity(Mp)
    J_cp = kron(Ip, J_cp_sub)
    """ d resc / d j : positive """
    Deff = vmap(coeffs.solidDiffCoeff)(peq.Ds * np.ones([Mp, 1]),
                                       peq.ED * np.ones([Mp, 1]),
                                       Tvec_pe[1:Mp + 1])
    dcj_p = 1 / Deff

    # build the jacobian for j
    row_cjp = onp.zeros(Mp, dtype=int)
    col_cjp = onp.arange(0, Mp)
    for i in range(0, Mp):
        row_cjp[i] = Np + 1 + i * (Np + 2)
    J_cjp = coo_matrix((dcj_p.ravel(), (row_cjp, col_cjp)),
                       shape=(Mp * (Np + 2), Mp))
    """ d resc / d T : positive """
    dcT_p = vmap(grad(peq.bc_neumann_c,
                      3))(cmat_pe[Np, 0:Mp], cmat_pe[Np + 1, 0:Mp], j_pe[0:Mp],
                          Tvec_pe[1:Mp + 1])
    #dcT_ps = grad(coeffs.solidDiffCoeff, 2)(peq.Ds, peq.ED, Tvec_pe[1])

    # build the jacobian for j
    row_cTp = onp.zeros(Mp, dtype=int)
    col_cTp = onp.arange(1, Mp + 1)
    for i in range(0, Mp):
        row_cTp[i] = Np + 1 + i * (Np + 2)
    J_cTp = coo_matrix((dcT_p.ravel(), (row_cTp, col_cTp)),
                       shape=(Mp * (Np + 2) + Mn * (Nn + 2), Mp + 2))
    """ Negative """
    res_cn = onp.zeros([(Nn + 2) * Mn, 1])
    for i in range(0, Mn):
        arg_cn = [
            cmat_ne[0:Nn, i], cmat_ne[1:Nn + 1, i], cmat_ne[2:Nn + 2, i],
            cmat_old_ne[1:Nn + 1, i]
        ]
        arg_c0n = [cmat_ne[0, i], cmat_ne[1, i]]
        arg_cMn = [cmat_ne[Nn, i], cmat_ne[Nn + 1, i], j_ne[i], Tvec_ne[i + 1]]
        res_cn[(i) * (Nn + 2)] = neq.bc_zero_neumann(*arg_c0n)
        res_cn[i * (Nn + 2) + 1:Nn + 1 + i * (Nn + 2)] = np.reshape(
            neq.solid_conc_2(*arg_cn), [Nn, 1])
        res_cn[(Nn + 1) + i * (Nn + 2)] = neq.bc_neumann_c(*arg_cMn)

    res_cn = np.asarray(res_cn)
    """ Linear Jacobian """
    bc_cn0_grad = np.array([[-1, 1]]).T
    A_cn = vmap(grad(neq.solid_conc_2, range(0, 3)))(*arg_cn)
    bc_cnM_grad = np.array([[-1, 1]]).T

    bcn = {"right": bc_cn0_grad, "left": bc_cnM_grad}
    J_cn_sub = build_tridiag_c(Nn, A_cn, **bcn)
    In = identity(Mn)
    J_cn = kron(In, J_cn_sub)
    """ d resc / d j : negative """
    Deffn = vmap(coeffs.solidDiffCoeff)(neq.Ds * np.ones([Mn, 1]),
                                        neq.ED * np.ones([Mn, 1]),
                                        Tvec_ne[1:Mn + 1])
    dcj_n = neq.hy / Deffn

    # build the jacobian for j
    row_cjn = onp.zeros(Mn, dtype=int)
    col_cjn = onp.arange(0, Mn)
    for i in range(0, Mn):
        row_cjn[i] = Nn + 1 + i * (Nn + 2)
    J_cjn = coo_matrix((dcj_n.ravel(), (row_cjn, col_cjn)),
                       shape=(Mn * (Nn + 2), Mn))
    """ d resc / d T : negative """
    dcT_n = vmap(grad(neq.bc_neumann_c,
                      3))(cmat_ne[Np, 0:Mp], cmat_ne[Np + 1, 0:Mp], j_ne[0:Mp],
                          Tvec_ne[1:Mp + 1])
    #dcT_ps = grad(coeffs.solidDiffCoeff, 2)(peq.Ds, peq.ED, Tvec_pe[1])

    # build the jacobian for j
    row_cTn = onp.zeros(Mn, dtype=int)
    col_cTn = onp.arange(1, Mn + 1)
    for i in range(0, Mn):
        row_cTn[i] = Nn + 1 + i * (Nn + 2) + Mp * (Np + 2)
    J_cTn = coo_matrix((dcT_n.ravel(), (row_cTn, col_cTn)),
                       shape=(Mn * (Nn + 2) + Mp * (Np + 2), Mn + 2))

    J_cc = block_diag((J_cp, J_cn))
    J_cj = block_diag((J_cjp, J_cjn))
    J_cT = hstack([
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Ma + 2), J_cTp,
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Ms + 2), J_cTn,
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Mz + 2)
    ])

    res_c = np.vstack((res_cp, res_cn))

    J_c = hstack([
        J_cc,
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Mp + 2 + Mn + 2 + Ms + 2),
        J_cT,
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Mp + 2 + Mn + 2 + Ms + 2),
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Mp + 2 + Mn + 2), J_cj,
        empty_rec(Mp * (Np + 2) + Mn * (Nn + 2), Mp + Mn)
    ])

    return res_c, J_c
Exemple #4
0
def jacres_eta(acc,pe,sep,ne,zcc):
    Mp = peq.M; Mn = neq.M; Ms = sepq.M; Ma = accq.M; Mz = zccq.M
    Np = peq.N; Nn = neq.N
    # over_poten(self,eta, phis,phie, T, cs, cmax):
    arg_etap = [pe.etavec[0:Mp], pe.phisvec[1:Mp+1], pe.phievec[1:Mp+1], pe.Tvec[1:Mp+1], pe.cmat[Np,:], pe.cmat[Np+1,:], pe.cmax*np.ones([Mp,1])]
    res_etap = vmap(peq.over_poten)(*arg_etap)
    A_etap = vmap((grad(peq.over_poten, range(0,len(arg_etap)-1))))(*arg_etap)
    
    J_etap = build_diag(Mp,A_etap[0],"square")
    J_etaphisp = build_diag(Mp,A_etap[1], "wide")
    J_etaphiep = build_diag(Mp,A_etap[2], "wide")
#    J_etajp = build_diag(Mp,A_etap[4],"square")
    J_etajp = empty_square(Mp)
    J_etaTp = build_diag(Mp,A_etap[3],"wide")
    
    col_cp = []
    data_cp = []
    row_cp = np.repeat( np.arange(0,Mp), 2)
    for i in range(0,Mp):
        col_cp.append([ Np + (Np+2)*i, Np+1 + (Np+2)*(i) ])
        data_cp.append([ A_etap[4][i], A_etap[5][i]])
    data_cp =  np.ravel(np.array(data_cp))
    col_cp =  np.ravel(np.array(col_cp))
    J_cp = coo_matrix((data_cp,(row_cp,col_cp)), shape = (Mp, Mp*(Np+2) + Mn*(Nn+2)) )
    
    """negative"""
    arg_etan = [ne.etavec[0:Mn], ne.phisvec[1:Mn+1], ne.phievec[1:Mn+1], ne.Tvec[1:Mn+1], ne.cmat[Nn,:], ne.cmat[Nn+1,:], ne.cmax*np.ones([Mn,1])]
    res_etan = vmap(neq.over_poten)(*arg_etan)
    A_etan = vmap((grad(neq.over_poten, range(0,len(arg_etan)-1))))(*arg_etan)
    
    J_etan = build_diag(Mn,A_etan[0],"square")
    J_etaphisn = build_diag(Mn,A_etan[1], "wide")
    J_etaphien = build_diag(Mn,A_etan[2], "wide")
#    J_etajn = build_diag(Mn,A_etan[4],"square")
    J_etajn = empty_square(Mn)
    J_etaTn = build_diag(Mn,A_etan[3],"wide")
    
    col_cn = []
    data_cn = []
    offset = (Np+2)*Mp
    row_cn = np.repeat(np.arange(0,Mn), 2)
    for i in range(0,Mn):
        col_cn.append([  Nn + (Nn+2)*i + offset, Nn+1 + (Nn+2)*(i) + offset ])
        data_cn.append([ A_etan[4][i], A_etan[5][i] ])
    data_cn =  np.ravel(np.array(data_cn))
    col_cn =  np.ravel(np.array(col_cn))
    J_cn = coo_matrix((data_cn,(row_cn,col_cn)), shape = (Mn, Mp*(Np+2) + Mn*(Nn+2)) )
    
    J_etaphis = hstack([
            vstack([J_etaphisp,empty_rec(Mn,Mp+2)]),
            vstack([empty_rec(Mp,Mn+2), J_etaphisn])
            ])
    
    J_etaphie = hstack([
            vstack([J_etaphiep, empty_rec(Mn, Mp+2)]),
            empty_rec(Mn+Mp,Ms+2),
            vstack([empty_rec(Mp, Mn+2), J_etaphien])
            ])
    
    J_etaT = hstack([
            empty_rec(Mp+Mn,Ma+2),
            vstack([J_etaTp,empty_rec(Mn,Mp+2)]),
            empty_rec(Mp+Mn,Ms+2),
            vstack([empty_rec(Mp,Mn+2), J_etaTn]),
            empty_rec(Mp+Mn,Mz+2)
            ])
    
    J_etaeta = block_diag((J_etap, J_etan))
    
    J_etaj = block_diag((J_etajp, J_etajn))
    
    J_etac = vstack([J_cp, J_cn])
    
    res_eta = np.hstack((res_etap, res_etan))
    J_eta = hstack([
            J_etac,
            empty_rec(Mp+Mn,Mp+2+Ms+2+Mn+2),
            J_etaT,
            J_etaphie,
            J_etaphis,
            J_etaj,
            J_etaeta
            ])
    
    return res_eta, J_eta
Exemple #5
0
def jacres_phis(acc, pe, sep, ne, zcc):
    Mp = peq.M
    Mn = neq.M
    Ms = sepq.M
    Ma = accq.M
    Mz = zccq.M
    Np = peq.N
    Nn = neq.N
    #    def solid_poten(self,phisn, phisc, phisp, j):
    #        hx = self.hx; a = self.a
    #        sigeff = self.sigma*(1-self.eps-self.epsf)
    #        ans = sigeff*( phisn - 2*phisc + phisp)/hx**2 - a*F*j
    #        return ans.reshape()
    #
    #    def bc_phis(self,phis0, phis1, source):
    #        sigeff = self.sigma*(1-pe.eps-pe.epsf)
    #        bc = sigeff*( phis1 - phis0 )/pe.hx - source
    #        return bc.reshape()
    """ Positive electrode"""
    arg_phis0p = [pe.phisvec[0], pe.phisvec[1], -Iapp]
    arg_phisp = [
        pe.phisvec[0:Mp], pe.phisvec[1:Mp + 1], pe.phisvec[2:Mp + 2],
        pe.jvec[0:Mp]
    ]
    arg_phisMp = [pe.phisvec[Mp], pe.phisvec[Mp + 1]]

    bc_phis0p = peq.bc_phis(*arg_phis0p)
    res_phisp = vmap(peq.solid_poten)(*arg_phisp)
    bc_phisMp = peq.bc_zero_neumann(*arg_phisMp)

    bc_phis0p_grad = grad(peq.bc_phis, range(0, 2))(*arg_phis0p)
    A_phisp = vmap(grad(peq.solid_poten, range(0, 4)))(*arg_phisp)
    bc_phisMp_grad = grad(peq.bc_zero_neumann, range(0, 2))(*arg_phisMp)

    bcphisp = {"right": bc_phis0p_grad, "left": bc_phisMp_grad}
    J_phisphisp = build_tridiag(Mp, A_phisp[0:3], **bcphisp)

    J_phisjp = build_diag(Mp, A_phisp[3], "long")
    """ Negative electrode"""
    arg_phis0n = [ne.phisvec[0], ne.phisvec[1]]
    arg_phisn = [
        ne.phisvec[0:Mn], ne.phisvec[1:Mn + 1], ne.phisvec[2:Mn + 2],
        ne.jvec[0:Mn]
    ]
    arg_phisMn = [ne.phisvec[Mn], ne.phisvec[Mn + 1], -Iapp]

    bc_phis0n = neq.bc_zero_neumann(*arg_phis0n)
    res_phisn = vmap(neq.solid_poten)(*arg_phisn)
    bc_phisMn = neq.bc_phis(*arg_phisMn)

    bc_phis0n_grad = grad(neq.bc_zero_neumann, range(0, 2))(*arg_phis0n)
    A_phisn = vmap(grad(neq.solid_poten, range(0, 4)))(*arg_phisn)
    bc_phisMn_grad = grad(neq.bc_phis, range(0, 2))(*arg_phisMn)

    bcphisn = {"right": bc_phis0n_grad, "left": bc_phisMn_grad}
    J_phisphisn = build_tridiag(Mn, A_phisn[0:3], **bcphisn)

    J_phisjn = build_diag(Mn, A_phisn[3], "long")

    J_phisphis = block_diag((J_phisphisp, J_phisphisn))
    J_phisj = block_diag((J_phisjp, J_phisjn))

    res_phis = np.hstack(
        (bc_phis0p, res_phisp, bc_phisMp, bc_phis0n, res_phisn, bc_phisMn))
    J_phis = hstack([
        empty_rec(Mp + 2 + Mn + 2,
                  Mp * (Np + 2) + Mn * (Nn + 2)),  #c
        empty_rec(Mp + 2 + Mn + 2, Mp + 2 + Ms + 2 + Mn + 2),  #u
        empty_rec(Mp + 2 + Mn + 2,
                  Ma + 2 + Mp + 2 + Ms + 2 + Mn + 2 + Mz + 2),  #T
        empty_rec(Mp + 2 + Mn + 2, Mp + 2 + Ms + 2 + Mn + 2),  #phie
        J_phisphis,
        J_phisj,
        empty_rec(Mp + 2 + Mn + 2, Mp + Mn)
    ])

    return res_phis, J_phis
Exemple #6
0
def jacres_u(U, Uold, peq, neq, sepq, accq, zccq):
    Mp = peq.M
    Mn = neq.M
    Ms = sepq.M
    Ma = accq.M
    Mz = zccq.M
    Np = peq.N
    Nn = neq.N

    cmat_pe, cmat_ne, \
    uvec_pe, uvec_sep, uvec_ne,\
    Tvec_acc, Tvec_pe, Tvec_sep, Tvec_ne, Tvec_zcc, \
    phie_pe, phie_sep, phie_ne, phis_pe, phis_ne, \
    j_pe,j_ne,eta_pe,eta_ne = unpack(U, Mp, Np, Mn, Nn, Ms, Ma, Mz)

    cmat_old_pe, cmat_old_ne,\
    uvec_old_pe, uvec_old_sep, uvec_old_ne,\
    Tvec_old_acc, Tvec_old_pe, Tvec_old_sep, Tvec_old_ne, Tvec_old_zcc,\
    _, _, \
    _, _,\
    _,_,\
    _,_,_= unpack(Uold,Mp, Np, Mn, Nn, Ms, Ma, Mz)

    bc_u0p = peq.bc_zero_neumann(uvec_pe[0], uvec_pe[1])
    res_up = vmap(peq.electrolyte_conc)(uvec_pe[0:Mp], uvec_pe[1:Mp + 1],
                                        uvec_pe[2:Mp + 2], Tvec_pe[0:Mp],
                                        Tvec_pe[1:Mp + 1], Tvec_pe[2:Mp + 2],
                                        j_pe[0:Mp], uvec_old_pe[1:Mp + 1])
    bc_uMp = peq.bc_u_sep_p(uvec_pe[Mp], uvec_pe[Mp + 1], Tvec_pe[Mp],
                            Tvec_pe[Mp + 1], uvec_sep[0], uvec_sep[1],
                            Tvec_sep[0], Tvec_sep[1])

    bc_u0s = peq.bc_inter_cont(uvec_pe[Mp], uvec_pe[Mp + 1], uvec_sep[0],
                               uvec_sep[1])
    res_us = vmap(sepq.electrolyte_conc)(uvec_sep[0:Ms], uvec_sep[1:Ms + 1],
                                         uvec_sep[2:Ms + 2], Tvec_sep[0:Ms],
                                         Tvec_sep[1:Ms + 1],
                                         Tvec_sep[2:Ms + 2],
                                         uvec_old_sep[1:Ms + 1])
    bc_uMs = sepq.bc_u_sep_n(uvec_ne[0], uvec_ne[1], Tvec_ne[0], Tvec_ne[1],
                             uvec_sep[Ms], uvec_sep[Ms + 1], Tvec_sep[Ms],
                             Tvec_sep[Ms + 1])

    bc_u0n = neq.bc_inter_cont(uvec_ne[0], uvec_ne[1], uvec_sep[Ms],
                               uvec_sep[Ms + 1])
    res_un = vmap(neq.electrolyte_conc)(uvec_ne[0:Mn], uvec_ne[1:Mn + 1],
                                        uvec_ne[2:Mn + 2], Tvec_ne[0:Mn],
                                        Tvec_ne[1:Mn + 1], Tvec_ne[2:Mn + 2],
                                        j_ne[0:Mn], uvec_old_ne[1:Mn + 1])
    bc_uMn = neq.bc_zero_neumann(uvec_ne[Mn], uvec_ne[Mn + 1])
    """ positive electrode"""
    arg_up = [
        uvec_pe[0:Mp], uvec_pe[1:Mp + 1], uvec_pe[2:Mp + 2], Tvec_pe[0:Mp],
        Tvec_pe[1:Mp + 1], Tvec_pe[2:Mp + 2], j_pe[0:Mp], uvec_old_pe[1:Mp + 1]
    ]
    arg_uMp = [
        uvec_pe[Mp], uvec_pe[Mp + 1], Tvec_pe[Mp], Tvec_pe[Mp + 1],
        uvec_sep[0], uvec_sep[1], Tvec_sep[0], Tvec_sep[1]
    ]

    A_up = vmap(grad(peq.electrolyte_conc, range(0, len(arg_up) - 1)))(*arg_up)
    bc_u0p_grad = np.array([[-1, 1]]).T
    bc_uMp_grad = ((jax.grad(peq.bc_u_sep_p, range(0,
                                                   len(arg_uMp)))))(*arg_uMp)

    #uu
    bc_uup = {"right": bc_u0p_grad[0:2], "left": bc_uMp_grad[0:2]}
    J_uupp = build_tridiag(Mp, A_up[0:3], **bc_uup)
    # interface boundar8
    J_uups = coo_matrix(
        (np.ravel(np.asarray(bc_uMp_grad[4:6])), ([Mp + 1, Mp + 1], [0, 1])),
        shape=(Mp + 2, Ms + 2 + Mn + 2))
    J_uup = hstack([J_uupp, J_uups])

    # uT
    bc_uTp = {"left": bc_uMp_grad[2:4]}
    J_uTpp = build_tridiag(Mp, A_up[3:6], **bc_uTp)
    # interface
    J_uTps = coo_matrix(
        (np.ravel(np.asarray(bc_uMp_grad[6:8])), ([Mp + 1, Mp + 1], [0, 1])),
        shape=(Mp + 2, Ms + 2 + Mn + 2))
    J_uTp = hstack([J_uTpp, J_uTps])

    # uj
    J_ujp = build_diag(Mp, A_up[6], "long")
    """ Separator """
    arg_u0s = [uvec_pe[Mp], uvec_pe[Mp + 1], uvec_sep[0], uvec_sep[1]]
    arg_us = [
        uvec_sep[0:Ms], uvec_sep[1:Ms + 1], uvec_sep[2:Ms + 2], Tvec_sep[0:Ms],
        Tvec_sep[1:Ms + 1], Tvec_sep[2:Ms + 2], uvec_old_sep[1:Ms + 1]
    ]
    arg_uMs = [
        uvec_ne[0], uvec_ne[1], Tvec_ne[0], Tvec_ne[1], uvec_sep[Ms],
        uvec_sep[Ms + 1], Tvec_sep[Ms], Tvec_sep[Ms + 1]
    ]

    A_us = vmap(grad(sepq.electrolyte_conc, range(0,
                                                  len(arg_us) - 1)))(*arg_us)
    bc_u0s_grad = (jax.grad(peq.bc_inter_cont, range(0,
                                                     len(arg_u0s))))(*arg_u0s)
    bc_uMs_grad = (jax.grad(sepq.bc_u_sep_n, range(0, len(arg_uMs))))(*arg_uMs)

    #uu
    bc_uus = {"right": bc_u0s_grad[2:4], "left": bc_uMs_grad[4:6]}
    J_uuss = build_tridiag(Ms, A_us[0:3], **bc_uus)
    # positive sep interface
    J_uusp = coo_matrix(
        (np.ravel(np.asarray(bc_u0s_grad[0:2])), ([0, 0], [Mp, Mp + 1])),
        shape=(Ms + 2, Mp + 2))
    #negative sep interface
    J_uusn = coo_matrix(
        (np.ravel(np.asarray(bc_uMs_grad[0:2])), ([Ms + 1, Ms + 1], [0, 1])),
        shape=(Ms + 2, Mn + 2))
    J_uus = hstack([J_uusp, J_uuss, J_uusn])

    # uT
    bc_uTs = {"left": bc_uMs_grad[6:8]}
    J_uTss = build_tridiag(Ms, A_us[3:6], **bc_uTs)
    #    J_uTsp = coo_matrix((np.ravel(np.asarray(bc_u0s_grad[2:4])),([0,0],[Mp,Mp+1] )),shape=(Ms+2,Mp+2))
    J_uTsp = empty_rec(Ms + 2, Mp + 2)
    J_uTsn = coo_matrix(
        (np.ravel(np.asarray(bc_uMs_grad[2:4])), ([Ms + 1, Ms + 1], [0, 1])),
        shape=(Ms + 2, Mn + 2))
    J_uTs = hstack([J_uTsp, J_uTss, J_uTsn])
    """ negative electrode"""
    arg_un = [
        uvec_ne[0:Mn], uvec_ne[1:Mn + 1], uvec_ne[2:Mn + 2], Tvec_ne[0:Mn],
        Tvec_ne[1:Mn + 1], Tvec_ne[2:Mn + 2], j_ne[0:Mn], uvec_old_ne[1:Mn + 1]
    ]
    arg_u0n = [uvec_ne[0], uvec_ne[1], uvec_sep[Ms], uvec_sep[Ms + 1]]

    A_un = vmap(grad(neq.electrolyte_conc, range(0, len(arg_un) - 1)))(*arg_un)
    bc_u0n_grad = grad(neq.bc_inter_cont, range(0, len(arg_u0n)))(*arg_u0n)
    bc_uMn_grad = np.array([[-1, 1]]).T

    #uu
    bc_uun = {"right": bc_u0n_grad[0:2], "left": bc_uMn_grad[0:2]}
    J_uunn = build_tridiag(Mn, A_un[0:3], **bc_uun)
    J_uuns = coo_matrix((np.ravel(np.asarray(bc_u0n_grad[2:4])),
                         ([0, 0], [Mp + 2 + Ms, Mp + 2 + Ms + 1])),
                        shape=(Mn + 2, Ms + 2 + Mp + 2))
    J_uun = hstack([J_uuns, J_uunn])
    # uT

    J_uTnn = build_tridiag(Mn, A_un[3:6])

    J_uTns = empty_rec(Mn + 2, Ms + 2 + Mp + 2)
    J_uTn = hstack([J_uTns, J_uTnn])

    # uj
    J_ujn = build_diag(Mn, A_un[6], "long")

    res_u = np.hstack((bc_u0p, res_up, bc_uMp, bc_u0s, res_us, bc_uMs, bc_u0n,
                       res_un, bc_uMn))

    J_u = hstack([
        empty_rec(Mp + 2 + Ms + 2 + Mn + 2,
                  Mp * (Np + 2) + Mn * (Nn + 2)),  # c
        vstack([J_uup, J_uus, J_uun]),
        hstack([
            empty_rec(Mp + 2 + Ms + 2 + Mn + 2, Ma + 2),  # acc 
            vstack([J_uTp, J_uTs, J_uTn]),
            empty_rec(Mp + 2 + Ms + 2 + Mn + 2, Mz + 2)  # zcc
        ]),
        empty_rec(Mp + 2 + Ms + 2 + Mn + 2, Mp + 2 + Ms + 2 + Mn + 2),  #phie
        empty_rec(Mp + 2 + Ms + 2 + Mn + 2, Mp + 2 + Mn + 2),  #phis
        vstack([
            hstack([J_ujp, empty_rec(Mp + 2, Mn)]),
            empty_rec(Ms + 2, Mp + Mn),
            hstack([empty_rec(Mn + 2, Mp), J_ujn])
        ]),
        empty_rec(Mp + 2 + Ms + 2 + Mn + 2, Mp + Mn)
    ])

    return res_u, J_u
Exemple #7
0
def jacres_phie(acc, pe, sep, ne, zcc):
    Mp = peq.M
    Mn = neq.M
    Ms = sepq.M
    Ma = accq.M
    Mz = zccq.M
    Np = peq.N
    Nn = neq.N
    """ Positive Electrode"""
    #electrolyte_poten(self,un, uc, up, phien, phiec, phiep, Tn, Tc, Tp,j):
    arg_phie0p = [pe.phievec[0], pe.phievec[1]]
    arg_phiep = [
        pe.uvec[0:Mp], pe.uvec[1:Mp + 1], pe.uvec[2:Mp + 2], pe.phievec[0:Mp],
        pe.phievec[1:Mp + 1], pe.phievec[2:Mp + 2], pe.Tvec[0:Mp],
        pe.Tvec[1:Mp + 1], pe.Tvec[2:Mp + 2], pe.jvec[0:Mp]
    ]
    #bc_phie_p(self,phie0_p, phie1_p, phie0_s, phie1_s, u0_p, u1_p, u0_s, u1_s, T0_p, T1_p, T0_s, T1_s)
    arg_phieMp = [
        pe.phievec[Mp], pe.phievec[Mp + 1], sep.phievec[0], sep.phievec[1],
        pe.uvec[Mp], pe.uvec[Mp + 1], sep.uvec[0], sep.uvec[1], pe.Tvec[Mp],
        pe.Tvec[Mp + 1], sep.Tvec[0], sep.Tvec[1]
    ]

    bc_phie0p = peq.bc_zero_neumann(*arg_phie0p)
    res_phiep = vmap(peq.electrolyte_poten)(*arg_phiep)
    bc_phieMp = peq.bc_phie_p(*arg_phieMp)

    bc_phie0p_grad = np.array([[-1, 1]]).T
    A_phiep = vmap((grad(peq.electrolyte_poten,
                         range(0, len(arg_phiep)))))(*arg_phiep)
    bc_phieMp_grad = grad(peq.bc_phie_p, range(0,
                                               len(arg_phieMp)))(*arg_phieMp)

    bcphiep = {"right": bc_phie0p_grad, "left": bc_phieMp_grad[0:2]}
    J_phiephiepp = build_tridiag(Mp, A_phiep[3:6], **bcphiep)
    J_phieps = coo_matrix((np.ravel(np.asarray(bc_phieMp_grad[2:4])),
                           ([Mp + 1, Mp + 1], [0, 1])),
                          shape=(Mp + 2, Ms + 2 + Mn + 2))
    J_phiephiep = hstack([J_phiephiepp, J_phieps])

    bc_phieup = {"left": bc_phieMp_grad[4:6]}
    J_phieupp = build_tridiag(Mp, A_phiep[0:3], **bc_phieup)
    J_phieups = coo_matrix((np.ravel(np.asarray(bc_phieMp_grad[6:8])),
                            ([Mp + 1, Mp + 1], [0, 1])),
                           shape=(Mp + 2, Ms + 2 + Mn + 2))
    J_phieup = hstack([J_phieupp, J_phieups])

    bc_phieTp = {"left": bc_phieMp_grad[8:10]}
    J_phieTpp = build_tridiag(Mp, A_phiep[6:9], **bc_phieTp)
    J_phieTps = coo_matrix((np.ravel(np.asarray(bc_phieMp_grad[10:12])),
                            ([Mp + 1, Mp + 1], [0, 1])),
                           shape=(Mp + 2, Ms + 2 + Mn + 2))
    J_phieTp = hstack([J_phieTpp, J_phieTps])

    J_phiejp = build_diag(Mp, A_phiep[9], "long")
    """ Separator """

    arg_phie0s = [
        sep.phievec[0], sep.phievec[1], pe.phievec[Mp], pe.phievec[Mp + 1]
    ]
    arg_phies = [
        sep.uvec[0:Ms], sep.uvec[1:Ms + 1], sep.uvec[2:Ms + 2],
        sep.phievec[0:Ms], sep.phievec[1:Ms + 1], sep.phievec[2:Ms + 2],
        sep.Tvec[0:Ms], sep.Tvec[1:Ms + 1], sep.Tvec[2:Ms + 2]
    ]
    # bc_phie_sn(self,phie0_n, phie1_n, phie0_s, phie1_s, u0_n, u1_n, u0_s, u1_s, T0_n, T1_n, T0_s, T1_s):
    arg_phieMs = [
        ne.phievec[0], ne.phievec[1], sep.phievec[Ms], sep.phievec[Ms + 1],
        ne.uvec[0], ne.uvec[1], sep.uvec[Ms], sep.uvec[Ms + 1], ne.Tvec[0],
        ne.Tvec[1], sep.Tvec[Ms], sep.Tvec[Ms + 1]
    ]

    bc_phie0s = peq.bc_inter_cont(*arg_phie0s)
    res_phies = vmap(sepq.electrolyte_poten)(*arg_phies)
    bc_phieMs = sepq.bc_phie_sn(*arg_phieMs)

    bc_phie0s_grad = grad(peq.bc_inter_cont,
                          range(0, len(arg_phie0s)))(*arg_phie0s)
    A_phies = vmap(grad(sepq.electrolyte_poten,
                        range(0, len(arg_phies))))(*arg_phies)
    bc_phieMs_grad = grad(sepq.bc_phie_sn, range(0,
                                                 len(arg_phieMs)))(*arg_phieMs)

    bcphies = {"right": bc_phie0s_grad[0:2], "left": bc_phieMs_grad[2:4]}
    J_phiephiess = build_tridiag(Ms, A_phies[3:6], **bcphies)
    J_phiephiesp = coo_matrix(
        (np.ravel(np.asarray(bc_phie0s_grad[2:4])), ([0, 0], [Mp, Mp + 1])),
        shape=(Ms + 2, Mp + 2))
    J_phiephiesn = coo_matrix((np.ravel(np.asarray(bc_phieMs_grad[0:2])),
                               ([Ms + 1, Ms + 1], [0, 1])),
                              shape=(Ms + 2, Mn + 2))
    J_phiephies = hstack([J_phiephiesp, J_phiephiess, J_phiephiesn])

    bcphieus = {"left": bc_phieMs_grad[6:8]}
    J_phieuss = build_tridiag(Ms, A_phies[0:3], **bcphieus)
    J_phieusp = empty_rec(Ms + 2, Mp + 2)
    J_phieusn = coo_matrix((np.ravel(np.asarray(bc_phieMs_grad[4:6])),
                            ([Ms + 1, Ms + 1], [0, 1])),
                           shape=(Ms + 2, Mn + 2))
    J_phieus = hstack([J_phieusp, J_phieuss, J_phieusn])

    bcphieTs = {"left": bc_phieMs_grad[10:12]}
    J_phieTss = build_tridiag(Ms, A_phies[6:9], **bcphieTs)
    J_phieTsp = empty_rec(Ms + 2, Mp + 2)
    J_phieTsn = coo_matrix((np.ravel(np.asarray(bc_phieMs_grad[8:10])),
                            ([Ms + 1, Ms + 1], [0, 1])),
                           shape=(Ms + 2, Mn + 2))
    J_phieTs = hstack([J_phieTsp, J_phieTss, J_phieTsn])
    """ Negative Electrode"""
    arg_phie0n = [
        ne.phievec[0], ne.phievec[1], sep.phievec[Ms], sep.phievec[Ms + 1]
    ]
    arg_phien = [
        ne.uvec[0:Mn], ne.uvec[1:Mn + 1], ne.uvec[2:Mn + 2], ne.phievec[0:Mn],
        ne.phievec[1:Mn + 1], ne.phievec[2:Mn + 2], ne.Tvec[0:Mn],
        ne.Tvec[1:Mn + 1], ne.Tvec[2:Mn + 2], ne.jvec[0:Mn]
    ]
    arg_phieMn = [ne.phievec[Mn], ne.phievec[Mn + 1]]

    bc_phie0n = neq.bc_inter_cont(*arg_phie0n)
    res_phien = vmap(neq.electrolyte_poten)(*arg_phien)
    bc_phieMn = neq.bc_zero_dirichlet(*arg_phieMn)

    bc_phie0n_grad = grad(neq.bc_inter_cont,
                          range(0, len(arg_phie0n)))(*arg_phie0n)
    A_phien = vmap(grad(neq.electrolyte_poten,
                        range(0, len(arg_phien))))(*arg_phien)
    bc_phieMn_grad = np.array([[1 / 2, 1 / 2]]).T

    bcphien = {"right": bc_phie0n_grad[0:2], "left": bc_phieMn_grad}
    J_phiephienn = build_tridiag(Mn, A_phien[3:6], **bcphien)
    J_phiephiens = coo_matrix((np.ravel(np.asarray(bc_phie0n_grad[2:4])),
                               ([0, 0], [Mp + 2 + Ms, Mp + 2 + Ms + 1])),
                              shape=(Mn + 2, Mp + 2 + Ms + 2))
    J_phiephien = hstack([J_phiephiens, J_phiephienn])

    J_phieunn = build_tridiag(Mn, A_phien[0:3])
    J_phieuns = empty_rec(Mn + 2, Mp + 2 + Ms + 2)
    J_phieun = hstack([J_phieuns, J_phieunn])

    J_phieTnn = build_tridiag(Mn, A_phien[6:9])
    J_phieTns = empty_rec(Mn + 2, Mp + 2 + Ms + 2)
    J_phieTn = hstack([J_phieTns, J_phieTnn])

    J_phiejn = build_diag(Mn, A_phien[9], "long")

    J_phieu = vstack((J_phieup, J_phieus, J_phieun))
    J_phiephie = vstack((J_phiephiep, J_phiephies, J_phiephien))
    J_phieT = hstack([
        empty_rec(Mp + 2 + Mn + 2 + Ms + 2, Ma + 2),
        vstack((J_phieTp, J_phieTs, J_phieTn)),
        empty_rec(Mp + 2 + Mn + 2 + Ms + 2, Mz + 2)
    ])
    J_phiej = vstack([
        hstack([J_phiejp, empty_rec(Mp + 2, Mn)]),
        empty_rec(Ms + 2, Mp + Mn),
        hstack([empty_rec(Mn + 2, Mp), J_phiejn])
    ])

    J_phiec = empty_rec(Mp + 2 + Ms + 2 + Mn + 2,
                        Mp * (Np + 2) + Mn * (Nn + 2))

    res_phie = np.hstack(
        (bc_phie0p, res_phiep, bc_phieMp, bc_phie0s, res_phies, bc_phieMs,
         bc_phie0n, res_phien, bc_phieMn))
    J_phie = hstack([
        J_phiec, J_phieu, J_phieT, J_phiephie,
        empty_rec(Mp + 2 + Mn + 2 + Ms + 2, Mp + 2 + Mn + 2), J_phiej,
        empty_rec(Mp + 2 + Ms + 2 + Mn + 2, Mp + Mn)
    ])

    return res_phie, J_phie