def __init__(self, Na, Ns, Nc, X, Ac, y0, yd0, name ) :

        Implicit_Problem.__init__(self,y0=y0,yd0=yd0,name=name)

        self.T  = 298.15 # Cell temperature, [K]
        self.Ac = Ac # Cell coated area, [m^2]

        # Control volumes and node points (mid node points and edge node points)
        self.Ns = Ns
        self.Na = Na
        self.Nc = Nc

        self.N = Na + Ns + Nc
        self.X = X

        self.x_e  = numpy.linspace( 0.0, X, N+1 )
        self.x_m  = numpy.array( [ 0.5*(self.x_e[i+1]+self.x_e[i]) for i in range(N) ], dtype='d'  )
        self.vols = numpy.array( [ (self.x_e[i+1] - self.x_e[i]) for i in range(N)], dtype='d' )

        # Useful sub-meshes for the phi_s functions
        self.x_m_a = self.x_m[:Na]
        self.x_m_c = self.x_m[-Nc:]
        self.x_e_a = self.x_e[:Na+1]
        self.x_e_c = self.x_e[-Nc-1:]

        self.vols_a = self.vols[:Na]
        self.vols_c = self.vols[-Nc:]

        # Volume fraction vectors and matrices for effective parameters
        self.La, self.Ls, self.Lc = self.Na*X/self.N, self.Ns*X/self.N, self.Nc*X/self.N
        self.Na, self.Ns, self.Nc = Na, Ns, Nc
        eps_a = 0.3
        eps_s = 0.5
        eps_c = 0.25
        ba, bs, bc = 0.8, 0.5, 0.5

        eps_a_vec = [ eps_a for i in range(Na) ] # list( eps_a + eps_a/2.*numpy.sin(numpy.linspace(0.,Na/4,Na)) ) # list(eps_a + eps_a*numpy.random.randn(Na)/5.) #
        eps_s_vec = [ eps_s for i in range(Ns) ]
        eps_c_vec = [ eps_c for i in range(Nc) ] # list( eps_c + eps_c/2.*numpy.sin(numpy.linspace(0.,Nc/4,Nc)) ) # list(eps_c + eps_c*numpy.random.randn(Nc)/5.) #

        self.eps_m   = numpy.array( eps_a_vec + eps_s_vec + eps_c_vec, dtype='d' )
        self.k_m     = 1./self.eps_m
        self.eps_mb  = numpy.array( [ ea**ba for ea in eps_a_vec ] + [ es**bs for es in eps_s_vec ] + [ ec**bc for ec in eps_c_vec ], dtype='d' )
        self.eps_eff = numpy.array( [ ea**(1.+ba) for ea in eps_a_vec ] + [ es**(1.+bs) for es in eps_s_vec ] + [ ec**(1.+bc) for ec in eps_c_vec ], dtype='d' )

        self.eps_a_eff = self.eps_eff[:Na]
        self.eps_c_eff = self.eps_eff[-Nc:]

        self.K_m = numpy.diag( self.k_m )

        t_plus = 0.4
        F = 96485.0

        self.t_plus = t_plus
        self.F = F
        self.R_gas = 8.314

        Rp_c = 6.5e-6
        Rp_a = 12.0e-6

        as_c = 3.*numpy.array(eps_c_vec, dtype='d')/Rp_c
        as_a = 3.*numpy.array(eps_a_vec, dtype='d')/Rp_a
        self.as_c = as_c
        self.as_a = as_a

        self.as_a_mean = 1./self.La*sum( [ asa*v for asa,v in zip(as_a, self.vols[:Na]) ] )
        self.as_c_mean = 1./self.Lc*sum( [ asc*v for asc,v in zip(as_c, self.vols[-Nc:]) ] )

        print 'asa diff', self.as_a_mean - as_a[0]
        print 'asc diff', self.as_c_mean - as_c[0]

        Ba = [ (1.-t_plus)*asa/ea for ea, asa in zip(eps_a_vec,as_a) ]
        Bs = [  0.0                for i in range(Ns) ]
        Bc = [ (1.-t_plus)*asc/ec for ec, asc in zip(eps_c_vec,as_c) ]

        self.B_ce = numpy.diag( numpy.array(Ba+Bs+Bc, dtype='d') )

#        Bap = [ asa*F*dxa for asa,dxa in zip(as_a,self.vols_a) ]
#        Bsp = [   0.0 for i   in range(Ns) ]
#        Bcp = [ asc*F*dxc for asc,dxc in zip(as_c,self.vols_c) ]
        Bap = [ asa*F for asa in as_a  ]
        Bsp = [   0.0 for i   in range(Ns) ]
        Bcp = [ asc*F for asc in as_c  ]

        self.B2_pe = numpy.diag( numpy.array(Bap+Bsp+Bcp, dtype='d') )

        # Solid phase parameters and j vector matrices
        self.sig_a = 100. # [S/m]
        self.sig_c = 100. # [S/m]

        self.sig_a_eff = self.sig_a * self.eps_a_eff
        self.sig_c_eff = self.sig_c * self.eps_c_eff

        self.A_ps_a = flux_mat_builder( self.Na, self.x_m_a, numpy.ones_like(self.vols_a), self.sig_a_eff )
        self.A_ps_c = flux_mat_builder( self.Nc, self.x_m_c, numpy.ones_like(self.vols_c), self.sig_c_eff )

        self.A_ps_a[-1,-1] = 2*self.A_ps_a[-1,-1]
        self.A_ps_c[ 0, 0] = 2*self.A_ps_c[ 0, 0]

        Baps = numpy.array( [ asa*F*dxa for asa,dxa in zip(as_a, self.vols_a) ], dtype='d' )
        Bcps = numpy.array( [ asc*F*dxc for asc,dxc in zip(as_c, self.vols_c) ], dtype='d' )

        self.B_ps_a = numpy.diag( Baps )
        self.B_ps_c = numpy.diag( Bcps )

        self.B2_ps_a = numpy.zeros( self.Na, dtype='d' )
        self.B2_ps_a[ 0] = -1.
        self.B2_ps_c = numpy.zeros( self.Nc, dtype='d' )
        self.B2_ps_c[-1] = -1.
示例#2
0
 def __init__(self, system, **kwargs):
     Implicit_Problem.__init__(self, **kwargs)
     self.name = 'ACAIE problem without concentration checks'
     self.system = system
示例#3
0
    def __init__(self, N, Ac, y0, yd0, name ) :

        Implicit_Problem.__init__(self,y0=y0,yd0=yd0,name=name)

        self.Ac = Ac
        self.T = 298.15

        La = 65.0
        Ls = 25.0
        Lc = 55.0
        Lt = (La+Ls+Lc)
        X = Lt*1e-6 # [m]

        Ns = int(N*(Ls/Lt))
        Na = int(N*(La/Lt))
        Nc = N - Ns - Na

        print 'Na, Nc:', Na, Nc

        self.N = N
        self.X = X

        self.x_e  = numpy.linspace( 0.0, X, N+1 )
        self.x_m  = numpy.array( [ 0.5*(self.x_e[i+1]+self.x_e[i]) for i in range(N) ], dtype='d'  )
        self.vols = numpy.array( [ (self.x_e[i+1] - self.x_e[i]) for i in range(N)], dtype='d' )

        ### Diffusivity
        self.La, self.Ls, self.Lc = La, Ls, Lc
        self.Na, self.Ns, self.Nc = Na, Ns, Nc
        eps_a = 0.25
        eps_s = 0.5
        eps_c = 0.2
        ba, bs, bc = 1.2, 0.5, 0.5

        eps_a_vec = [ eps_a for i in range(Na) ] # list( eps_a + eps_a/2.*numpy.sin(numpy.linspace(0.,Na/4,Na)) ) # list(eps_a + eps_a*numpy.random.randn(Na)/5.) #
        eps_s_vec = [ eps_s for i in range(Ns) ]
        eps_c_vec = [ eps_c for i in range(Nc) ] # list( eps_c + eps_c/2.*numpy.sin(numpy.linspace(0.,Nc/4,Nc)) ) # list(eps_c + eps_c*numpy.random.randn(Nc)/5.) #

        self.eps_m   = numpy.array( eps_a_vec + eps_s_vec + eps_c_vec, dtype='d' )
        self.k_m     = 1./self.eps_m
        self.eps_mb  = numpy.array( [ ea**ba for ea in eps_a_vec ] + [ es**bs for es in eps_s_vec ] + [ ec**bc for ec in eps_c_vec ], dtype='d' )
        self.eps_eff = numpy.array( [ ea**(1.+ba) for ea in eps_a_vec ] + [ es**(1.+bs) for es in eps_s_vec ] + [ ec**(1.+bc) for ec in eps_c_vec ], dtype='d' )

        self.K_m = numpy.diag( self.k_m )

        self.pe0_ind = self.Na+self.Ns+self.Nc-3

        t_plus = 0.4
        F = 96485.0

        self.t_plus = t_plus
        self.F = F
        self.R_gas = 8.314

        Rp_c = 6.5e-6
        Rp_a = 12.0e-6

        as_c = 3.*numpy.array(eps_c_vec, dtype='d')/Rp_c
        as_a = 3.*numpy.array(eps_a_vec, dtype='d')/Rp_a
        self.as_c = as_c
        self.as_a = as_a

        self.as_a_mean = 1./self.La*sum( [ asa*v for asa,v in zip(as_a, self.vols[:Na]) ] )
        self.as_c_mean = 1./self.Lc*sum( [ asc*v for asc,v in zip(as_c, self.vols[-Nc:]) ] )

        print 'asa diff', self.as_a_mean - as_a[0]
        print 'asc diff', self.as_c_mean - as_c[0]

        Ba = [ (1.-t_plus)*asa/ea for ea, asa in zip(eps_a_vec,as_a) ]
        Bs = [  0.0                for i in range(Ns) ]
        Bc = [ (1.-t_plus)*asc/ec for ec, asc in zip(eps_c_vec,as_c) ]

        self.B_ce = numpy.diag( numpy.array(Ba+Bs+Bc, dtype='d') )

        Bap = [ asa*F*v for asa,v in zip(as_a,self.vols[:Na]) ]
        Bsp = [   0.0 for i   in range(Ns) ]
        Bcp = [ asc*F*v for asc,v in zip(as_c,self.vols[-Nc:]) ]
#        Bap = [ asa*F for asa in as_a ]
#        Bsp = [   0.0 for i   in range(Ns) ]
#        Bcp = [ asc*F for asc in as_c ]

        self.B2_pe = numpy.diag( numpy.array(Bap+Bsp+Bcp, dtype='d') )
示例#4
0
    def __init__(self, Na, Ns, Nc, X, Ac, bsp_dir, y0, yd0, name):

        Implicit_Problem.__init__(self, y0=y0, yd0=yd0, name=name)

        self.T = 298.15  # Cell temperature, [K]
        self.Ac = Ac  # Cell coated area, [m^2]

        # Control volumes and node points (mid node points and edge node points)
        self.Ns = Ns
        self.Na = Na
        self.Nc = Nc

        self.N = Na + Ns + Nc
        self.X = X

        self.num_diff_vars = N + Na + Nc
        self.num_algr_vars = Na + Nc + N + Na + Nc

        self.x_e = numpy.linspace(0.0, X, N + 1)
        self.x_m = numpy.array(
            [0.5 * (self.x_e[i + 1] + self.x_e[i]) for i in range(N)],
            dtype='d')
        self.vols = numpy.array([(self.x_e[i + 1] - self.x_e[i])
                                 for i in range(N)],
                                dtype='d')

        # Useful sub-meshes for the phi_s functions
        self.x_m_a = self.x_m[:Na]
        self.x_m_c = self.x_m[-Nc:]
        self.x_e_a = self.x_e[:Na + 1]
        self.x_e_c = self.x_e[-Nc - 1:]

        self.vols_a = self.vols[:Na]
        self.vols_c = self.vols[-Nc:]

        # Volume fraction vectors and matrices for effective parameters
        self.La, self.Ls, self.Lc = self.Na * X / self.N, self.Ns * X / self.N, self.Nc * X / self.N
        self.Na, self.Ns, self.Nc = Na, Ns, Nc
        eps_a = 0.25
        eps_s = 0.5
        eps_c = 0.2
        ba, bs, bc = 1.2, 0.5, 0.5

        eps_a_vec = [
            eps_a for i in range(Na)
        ]  # list( eps_a + eps_a/2.*numpy.sin(numpy.linspace(0.,Na/4,Na)) ) # list(eps_a + eps_a*numpy.random.randn(Na)/5.) #
        eps_s_vec = [eps_s for i in range(Ns)]
        eps_c_vec = [
            eps_c for i in range(Nc)
        ]  # list( eps_c + eps_c/2.*numpy.sin(numpy.linspace(0.,Nc/4,Nc)) ) # list(eps_c + eps_c*numpy.random.randn(Nc)/5.) #

        self.eps_m = numpy.array(eps_a_vec + eps_s_vec + eps_c_vec, dtype='d')
        self.k_m = 1. / self.eps_m
        self.eps_mb = numpy.array([ea**ba for ea in eps_a_vec] +
                                  [es**bs for es in eps_s_vec] +
                                  [ec**bc for ec in eps_c_vec],
                                  dtype='d')
        self.eps_eff = numpy.array([ea**(1. + ba) for ea in eps_a_vec] +
                                   [es**(1. + bs) for es in eps_s_vec] +
                                   [ec**(1. + bc) for ec in eps_c_vec],
                                   dtype='d')

        self.eps_a_eff = self.eps_eff[:Na]
        self.eps_c_eff = self.eps_eff[-Nc:]

        self.K_m = numpy.diag(self.k_m)

        t_plus = 0.43
        F = 96485.0

        self.t_plus = t_plus
        self.F = F
        self.R_gas = 8.314

        Rp_a = 12.0e-6
        Rp_c = 6.5e-6
        self.Rp_a = Rp_a
        self.Rp_c = Rp_c

        as_a = 3. * (1.0 - numpy.array(eps_a_vec, dtype='d')) / Rp_a
        as_c = 3. * (1.0 - numpy.array(eps_c_vec, dtype='d')) / Rp_c
        self.as_a = as_a
        self.as_c = as_c

        self.as_a_mean = 1. / self.La * sum(
            [asa * v for asa, v in zip(as_a, self.vols[:Na])])
        self.as_c_mean = 1. / self.Lc * sum(
            [asc * v for asc, v in zip(as_c, self.vols[-Nc:])])

        print 'asa diff', self.as_a_mean - as_a[0]
        print 'asc diff', self.as_c_mean - as_c[0]

        Ba = [(1. - t_plus) * asa / ea for ea, asa in zip(eps_a_vec, as_a)]
        Bs = [0.0 for i in range(Ns)]
        Bc = [(1. - t_plus) * asc / ec for ec, asc in zip(eps_c_vec, as_c)]

        self.B_ce = numpy.diag(numpy.array(Ba + Bs + Bc, dtype='d'))

        Bap = [asa * F for asa in as_a]
        Bsp = [0.0 for i in range(Ns)]
        Bcp = [asc * F for asc in as_c]

        self.B2_pe = numpy.diag(numpy.array(Bap + Bsp + Bcp, dtype='d'))

        # Interpolators for De, ke
        self.De_intp = build_interp_2d(
            bsp_dir + 'data/Model_v1/Model_Pars/electrolyte/De.csv')
        self.ke_intp = build_interp_2d(
            bsp_dir + 'data/Model_v1/Model_Pars/electrolyte/kappa.csv')
        self.fca_intp = build_interp_2d(
            bsp_dir + 'data/Model_v1/Model_Pars/electrolyte/fca.csv')

        self.ce_nom = 1000.0

        ######
        ## Solid phase parameters and j vector matrices
        self.sig_a = 100.  # [S/m]
        self.sig_c = 40.  # [S/m]

        self.sig_a_eff = self.sig_a * (1.0 - self.eps_a_eff)
        self.sig_c_eff = self.sig_c * (1.0 - self.eps_c_eff)

        self.A_ps_a = flux_mat_builder(self.Na, self.x_m_a,
                                       numpy.ones_like(self.vols_a),
                                       self.sig_a_eff)
        self.A_ps_c = flux_mat_builder(self.Nc, self.x_m_c,
                                       numpy.ones_like(self.vols_c),
                                       self.sig_c_eff)

        # Grounding form for BCs (was only needed during testing, before BVK was incorporated for coupling
        Baps = numpy.array(
            [asa * F * dxa for asa, dxa in zip(as_a, self.vols_a)], dtype='d')
        Bcps = numpy.array(
            [asc * F * dxc for asc, dxc in zip(as_c, self.vols_c)], dtype='d')
        self.B_ps_a = numpy.diag(Baps)
        self.B_ps_c = numpy.diag(Bcps)

        self.B2_ps_a = numpy.zeros(self.Na, dtype='d')
        self.B2_ps_a[0] = -1.
        self.B2_ps_c = numpy.zeros(self.Nc, dtype='d')
        self.B2_ps_c[-1] = -1.

        # Two parameter Solid phase diffusion model
        Dsa = 1e-12
        Dsc = 1e-14
        self.Dsa = Dsa
        self.Dsc = Dsc

        self.csa_max = 30555.0  # [mol/m^3]
        self.csc_max = 51554.0  # [mol/m^3]

        self.B_cs_a = numpy.diag(
            numpy.array([-3.0 / Rp_a for i in range(Na)], dtype='d'))
        self.B_cs_c = numpy.diag(
            numpy.array([-3.0 / Rp_c for i in range(Nc)], dtype='d'))

        self.C_cs_a = numpy.eye(Na)
        self.C_cs_c = numpy.eye(Nc)

        self.D_cs_a = numpy.diag(
            numpy.array([-Rp_a / Dsa / 5.0 for i in range(Na)], dtype='d'))
        self.D_cs_c = numpy.diag(
            numpy.array([-Rp_c / Dsc / 5.0 for i in range(Nc)], dtype='d'))

        #        bsp_dir = '/home/m_klein/Projects/battsimpy/'
        #        bsp_dir = '/home/mk-sim-linux/Battery_TempGrad/Python/batt_simulation/battsimpy/'

        uref_a_map = numpy.loadtxt(
            bsp_dir +
            '/data/Model_v1/Model_Pars/solid/thermodynamics/uref_anode_x.csv',
            delimiter=',')
        uref_c_map = numpy.loadtxt(
            bsp_dir +
            '/data/Model_v1/Model_Pars/solid/thermodynamics/uref_cathode_x.csv',
            delimiter=',')

        duref_a = numpy.gradient(uref_a_map[:, 1]) / numpy.gradient(
            uref_a_map[:, 0])
        duref_c = numpy.gradient(uref_c_map[:, 1]) / numpy.gradient(
            uref_c_map[:, 0])

        if uref_a_map[1, 0] > uref_a_map[0, 0]:
            self.uref_a_interp = scipy.interpolate.interp1d(
                uref_a_map[:, 0], uref_a_map[:, 1])
            self.duref_a_interp = scipy.interpolate.interp1d(
                uref_a_map[:, 0], duref_a)
        else:
            self.uref_a_interp = scipy.interpolate.interp1d(
                numpy.flipud(uref_a_map[:, 0]), numpy.flipud(uref_a_map[:, 1]))
            self.duref_a_interp = scipy.interpolate.interp1d(
                numpy.flipud(uref_a_map[:, 0]), numpy.flipud(duref_a))

        if uref_c_map[1, 0] > uref_c_map[0, 0]:
            self.uref_c_interp = scipy.interpolate.interp1d(
                uref_c_map[:, 0], uref_c_map[:, 1])
            self.duref_c_interp = scipy.interpolate.interp1d(
                uref_c_map[:, 0], duref_c)
        else:
            self.uref_c_interp = scipy.interpolate.interp1d(
                numpy.flipud(uref_c_map[:, 0]), numpy.flipud(uref_c_map[:, 1]))
            self.duref_c_interp = scipy.interpolate.interp1d(
                numpy.flipud(uref_c_map[:, 0]), numpy.flipud(duref_c))

        # Plot the Uref data for verification


#        xa = numpy.linspace( 0.05, 0.95, 50 )
#        xc = numpy.linspace( 0.40, 0.95, 50 )
#        plt.figure()
#        plt.plot( uref_a_map[:,0], uref_a_map[:,1], label='Ua map' )
#        plt.plot( uref_c_map[:,0], uref_c_map[:,1], label='Uc map' )

#        plt.plot( xa, self.uref_a_interp(xa), label='Ua interp' )
#        plt.plot( xc, self.uref_c_interp(xc), label='Uc interp' )
#        plt.legend()

#        plt.figure()
#        plt.plot( uref_a_map[:,0], duref_a, label='dUa map' )
#        plt.plot( uref_c_map[:,0], duref_c, label='dUc map' )

#        plt.plot( xa, self.duref_a_interp(xa), label='dUa interp' )
#        plt.plot( xc, self.duref_c_interp(xc), label='dUc interp' )
#        plt.legend()

#        plt.show()

# Reaction kinetics parameters
        self.io_a = 5.0  # [A/m^2]
        self.io_c = 5.0  # [A/m^2]

        # System indices
        self.ce_inds = range(self.N)
        self.csa_inds = range(self.N, self.N + self.Na)
        self.csc_inds = range(self.N + self.Na, self.N + self.Na + self.Nc)

        c_end = self.N + self.Na + self.Nc

        self.ja_inds = range(c_end, c_end + self.Na)
        self.jc_inds = range(c_end + self.Na, c_end + self.Na + self.Nc)

        self.pe_inds = range(c_end + self.Na + self.Nc,
                             c_end + self.Na + self.Nc + self.N)
        self.pe_a_inds = range(c_end + self.Na + self.Nc,
                               c_end + self.Na + self.Nc + self.Na)
        self.pe_c_inds = range(c_end + self.Na + self.Nc + self.Na + self.Ns,
                               c_end + self.Na + self.Nc + self.N)

        self.pa_inds = range(c_end + self.Na + self.Nc + self.N,
                             c_end + self.Na + self.Nc + self.N + self.Na)
        self.pc_inds = range(
            c_end + self.Na + self.Nc + self.N + self.Na,
            c_end + self.Na + self.Nc + self.N + self.Na + self.Nc)
示例#5
0
    def __init__(self, Na, Ns, Nc, Nra, Nrc, X, Ra, Rc, Ac, bsp_dir, y0, yd0,
                 name):

        Implicit_Problem.__init__(self, y0=y0, yd0=yd0, name=name)

        self.T = 298.15  # Cell temperature, [K]
        self.Ac = Ac  # Cell coated area, [m^2]

        # Control volumes and node points (mid node points and edge node points)
        self.Ns = Ns
        self.Na = Na
        self.Nc = Nc

        self.N = Na + Ns + Nc
        self.X = X

        self.x_e = numpy.linspace(0.0, X, N + 1)
        self.x_m = numpy.array(
            [0.5 * (self.x_e[i + 1] + self.x_e[i]) for i in range(N)],
            dtype='d')
        self.vols = numpy.array([(self.x_e[i + 1] - self.x_e[i])
                                 for i in range(N)],
                                dtype='d')

        # Radial mesh
        self.Nra = Nra
        self.Nrc = Nrc

        k = 0.8
        self.r_e_a = nonlinspace(Ra, k, Nra)
        self.r_m_a = numpy.array([
            0.5 * (self.r_e_a[i + 1] + self.r_e_a[i]) for i in range(Nra - 1)
        ],
                                 dtype='d')
        self.r_e_c = nonlinspace(Rc, k, Nrc)
        self.r_m_c = numpy.array([
            0.5 * (self.r_e_c[i + 1] + self.r_e_c[i]) for i in range(Nrc - 1)
        ],
                                 dtype='d')
        self.vols_ra_e = numpy.array([1 / 3. * (self.r_m_a[0]**3)] + [
            1 / 3. * (self.r_m_a[i + 1]**3 - self.r_m_a[i]**3)
            for i in range(Nra - 2)
        ] + [1 / 3. * (self.r_e_a[-1]**3 - self.r_m_a[-1]**3)],
                                     dtype='d')
        self.vols_rc_e = numpy.array([1 / 3. * (self.r_m_c[0]**3)] + [
            1 / 3. * (self.r_m_c[i + 1]**3 - self.r_m_c[i]**3)
            for i in range(Nrc - 2)
        ] + [1 / 3. * (self.r_e_c[-1]**3 - self.r_m_c[-1]**3)],
                                     dtype='d')
        self.vols_ra_m = numpy.array([
            1 / 3. * (self.r_e_a[i + 1]**3 - self.r_e_a[i]**3)
            for i in range(Nra - 1)
        ],
                                     dtype='d')
        self.vols_rc_m = numpy.array([
            1 / 3. * (self.r_e_c[i + 1]**3 - self.r_e_c[i]**3)
            for i in range(Nrc - 1)
        ],
                                     dtype='d')

        # Useful sub-meshes for the phi_s functions
        self.x_m_a = self.x_m[:Na]
        self.x_m_c = self.x_m[-Nc:]
        self.x_e_a = self.x_e[:Na + 1]
        self.x_e_c = self.x_e[-Nc - 1:]

        self.vols_a = self.vols[:Na]
        self.vols_c = self.vols[-Nc:]

        self.num_diff_vars = self.N + self.Nra * self.Na + self.Nrc * self.Nc
        self.num_algr_vars = self.N + self.Na + self.Nc

        # Volume fraction vectors and matrices for effective parameters
        self.La, self.Ls, self.Lc = self.Na * X / self.N, self.Ns * X / self.N, self.Nc * X / self.N
        self.Na, self.Ns, self.Nc = Na, Ns, Nc
        eps_a = 0.3
        eps_s = 0.5
        eps_c = 0.25
        ba, bs, bc = 0.8, 0.5, 0.5

        eps_a_vec = [
            eps_a for i in range(Na)
        ]  # list( eps_a + eps_a/2.*numpy.sin(numpy.linspace(0.,Na/4,Na)) ) # list(eps_a + eps_a*numpy.random.randn(Na)/5.) #
        eps_s_vec = [eps_s for i in range(Ns)]
        eps_c_vec = [
            eps_c for i in range(Nc)
        ]  # list( eps_c + eps_c/2.*numpy.sin(numpy.linspace(0.,Nc/4,Nc)) ) # list(eps_c + eps_c*numpy.random.randn(Nc)/5.) #

        self.eps_m = numpy.array(eps_a_vec + eps_s_vec + eps_c_vec, dtype='d')
        self.k_m = 1. / self.eps_m
        self.eps_mb = numpy.array([ea**ba for ea in eps_a_vec] +
                                  [es**bs for es in eps_s_vec] +
                                  [ec**bc for ec in eps_c_vec],
                                  dtype='d')
        self.eps_eff = numpy.array([ea**(1. + ba) for ea in eps_a_vec] +
                                   [es**(1. + bs) for es in eps_s_vec] +
                                   [ec**(1. + bc) for ec in eps_c_vec],
                                   dtype='d')

        self.eps_a_eff = self.eps_eff[:Na]
        self.eps_c_eff = self.eps_eff[-Nc:]

        self.K_m = numpy.diag(self.k_m)

        t_plus = 0.4
        F = 96485.0

        self.t_plus = t_plus
        self.F = F
        self.R_gas = 8.314

        self.Rp_a = Ra
        self.Rp_c = Rc

        as_a = 3. * numpy.array(eps_a_vec, dtype='d') / self.Rp_a
        as_c = 3. * numpy.array(eps_c_vec, dtype='d') / self.Rp_c
        self.as_a = as_a
        self.as_c = as_c

        self.as_a_mean = 1. / self.La * sum(
            [asa * v for asa, v in zip(as_a, self.vols[:Na])])
        self.as_c_mean = 1. / self.Lc * sum(
            [asc * v for asc, v in zip(as_c, self.vols[-Nc:])])

        print 'asa diff', self.as_a_mean - as_a[0]
        print 'asc diff', self.as_c_mean - as_c[0]

        # Electrolyte constant B_ce matrix
        Ba = [(1. - t_plus) * asa / ea for ea, asa in zip(eps_a_vec, as_a)]
        Bs = [0.0 for i in range(Ns)]
        Bc = [(1. - t_plus) * asc / ec for ec, asc in zip(eps_c_vec, as_c)]

        self.B_ce = numpy.diag(numpy.array(Ba + Bs + Bc, dtype='d'))

        Bap = [asa * F for asa in as_a]
        Bsp = [0.0 for i in range(Ns)]
        Bcp = [asc * F for asc in as_c]

        self.B2_pe = numpy.diag(numpy.array(Bap + Bsp + Bcp, dtype='d'))

        # Solid phase parameters and j vector matrices
        self.sig_a = 100.  # [S/m]
        self.sig_c = 100.  # [S/m]

        self.sig_a_eff = self.sig_a * self.eps_a_eff
        self.sig_c_eff = self.sig_c * self.eps_c_eff

        self.A_ps_a = flux_mat_builder(self.Na, self.x_m_a,
                                       numpy.ones_like(self.vols_a),
                                       self.sig_a_eff)
        self.A_ps_c = flux_mat_builder(self.Nc, self.x_m_c,
                                       numpy.ones_like(self.vols_c),
                                       self.sig_c_eff)

        # Grounding form for BCs (was only needed during testing, before BVK was incorporated for coupling
        self.A_ps_a[-1, -1] = 2 * self.A_ps_a[-1, -1]
        self.A_ps_c[0, 0] = 2 * self.A_ps_c[0, 0]

        Baps = numpy.array(
            [asa * F * dxa for asa, dxa in zip(as_a, self.vols_a)], dtype='d')
        Bcps = numpy.array(
            [asc * F * dxc for asc, dxc in zip(as_c, self.vols_c)], dtype='d')

        self.B_ps_a = numpy.diag(Baps)
        self.B_ps_c = numpy.diag(Bcps)

        self.B2_ps_a = numpy.zeros(self.Na, dtype='d')
        self.B2_ps_a[0] = -1.
        self.B2_ps_c = numpy.zeros(self.Nc, dtype='d')
        self.B2_ps_c[-1] = -1.

        # Solid phase diffusion model
        Dsa = 1e-12
        Dsc = 1e-14
        self.Dsa = Dsa
        self.Dsc = Dsc

        self.csa_max = 30555.0  # [mol/m^3]
        self.csc_max = 51554.0  # [mol/m^3]

        # Two parameter Solid phase diffusion model
        #        self.B_cs_a = numpy.diag( numpy.array( [-3.0/self.Rp_a for i in range(Na)], dtype='d' ) )
        #        self.B_cs_c = numpy.diag( numpy.array( [-3.0/self.Rp_c for i in range(Nc)], dtype='d' ) )

        #        self.C_cs_a = numpy.eye(Na)
        #        self.C_cs_c = numpy.eye(Nc)

        #        self.D_cs_a = numpy.diag( numpy.array( [-self.Rp_a/Dsa/5.0 for i in range(Na)], dtype='d' ) )
        #        self.D_cs_c = numpy.diag( numpy.array( [-self.Rp_c/Dsc/5.0 for i in range(Nc)], dtype='d' ) )

        # 1D spherical diffusion model
        self.A_csa_single = self.build_Ac_mat(
            Nra, Dsa * numpy.ones_like(self.r_m_a), self.r_m_a, self.r_e_a,
            self.vols_ra_e)
        self.A_csc_single = self.build_Ac_mat(
            Nrc, Dsc * numpy.ones_like(self.r_m_c), self.r_m_c, self.r_e_c,
            self.vols_rc_e)

        #        b = self.A_csa_single.reshape(1,Nra,Nra).repeat(Na,axis=0)
        b = [self.A_csa_single] * Na
        self.A_cs_a = scipy.linalg.block_diag(*b)
        b = [self.A_csc_single] * Nc
        self.A_cs_c = scipy.linalg.block_diag(*b)

        B_csa_single = numpy.array([0. for i in range(Nra)], dtype='d')
        B_csa_single[-1] = -1. * self.r_e_a[-1]**2
        A1 = self.build_Mc_A1mat(self.vols_ra_e)
        self.B_csa_single = A1.dot(B_csa_single)

        B_csc_single = numpy.array([0. for i in range(Nrc)], dtype='d')
        B_csc_single[-1] = -1. * self.r_e_c[-1]**2
        A1 = self.build_Mc_A1mat(self.vols_rc_e)
        self.B_csc_single = A1.dot(B_csc_single)

        b = [self.B_csa_single] * Na
        self.B_cs_a = scipy.linalg.block_diag(*b).T
        b = [self.B_csc_single] * Nc
        self.B_cs_c = scipy.linalg.block_diag(*b).T

        self.D_cs_a = scipy.linalg.block_diag(
            *[[0.0 for i in range(self.Nra - 1)] + [1.0]] * Na)
        self.D_cs_c = scipy.linalg.block_diag(
            *[[0.0 for i in range(self.Nrc - 1)] + [1.0]] * Nc)

        # OCV
        Ua_path = bsp_dir + 'data/Model_v1/Model_Pars/solid/thermodynamics/uref_anode_bigx.csv'
        Uc_path = bsp_dir + 'data/Model_v1/Model_Pars/solid/thermodynamics/uref_cathode_bigx.csv'

        self.uref_a, self.uref_c, self.duref_a, self.duref_c = get_smooth_Uref_data(
            Ua_path, Uc_path, ffa=0.4, ffc=0.2)

        # Reaction kinetics parameters
        self.io_a = 1.0  # [A/m^2]
        self.io_c = 1.0  # [A/m^2]

        ## System indices
        # Differential vars
        self.ce_inds = range(self.N)
        self.ce_inds_r = numpy.reshape(self.ce_inds, [len(self.ce_inds), 1])
        self.ce_inds_c = numpy.reshape(self.ce_inds, [1, len(self.ce_inds)])

        self.csa_inds = range(self.N, self.N + (self.Na * self.Nra))
        self.csa_inds_r = numpy.reshape(self.csa_inds, [len(self.csa_inds), 1])
        self.csa_inds_c = numpy.reshape(self.csa_inds, [1, len(self.csa_inds)])

        self.csc_inds = range(
            self.N + (self.Na * self.Nra),
            self.N + (self.Na * self.Nra) + (self.Nc * self.Nrc))
        self.csc_inds_r = numpy.reshape(self.csc_inds, [len(self.csc_inds), 1])
        self.csc_inds_c = numpy.reshape(self.csc_inds, [1, len(self.csc_inds)])

        # Algebraic vars
        c_end = self.N + (self.Na * self.Nra) + (self.Nc * self.Nrc)
        self.pe_inds = range(c_end, c_end + self.N)
        self.pe_inds_r = numpy.reshape(self.pe_inds, [len(self.pe_inds), 1])
        self.pe_inds_c = numpy.reshape(self.pe_inds, [1, len(self.pe_inds)])

        self.pe_a_inds = range(c_end, c_end + self.Na)
        self.pe_a_inds_r = numpy.reshape(self.pe_a_inds,
                                         [len(self.pe_a_inds), 1])
        self.pe_a_inds_c = numpy.reshape(self.pe_a_inds,
                                         [1, len(self.pe_a_inds)])

        self.pe_c_inds = range(c_end + self.Na + self.Ns,
                               c_end + self.Na + self.Ns + self.Nc)
        self.pe_c_inds_r = numpy.reshape(self.pe_c_inds,
                                         [len(self.pe_c_inds), 1])
        self.pe_c_inds_c = numpy.reshape(self.pe_c_inds,
                                         [1, len(self.pe_c_inds)])

        self.pa_inds = range(c_end + self.N, c_end + self.N + self.Na)
        self.pa_inds_r = numpy.reshape(self.pa_inds, [len(self.pa_inds), 1])
        self.pa_inds_c = numpy.reshape(self.pa_inds, [1, len(self.pa_inds)])

        self.pc_inds = range(c_end + self.N + self.Na,
                             c_end + self.N + self.Na + self.Nc)
        self.pc_inds_r = numpy.reshape(self.pc_inds, [len(self.pc_inds), 1])
        self.pc_inds_c = numpy.reshape(self.pc_inds, [1, len(self.pc_inds)])

        # second set for manual jac version
        c_end = 0
        self.pe_inds2 = range(c_end, c_end + self.N)
        self.pe_inds_r2 = numpy.reshape(self.pe_inds2, [len(self.pe_inds2), 1])
        self.pe_inds_c2 = numpy.reshape(self.pe_inds2, [1, len(self.pe_inds2)])

        self.pe_a_inds2 = range(c_end, c_end + self.Na)
        self.pe_a_inds_r2 = numpy.reshape(self.pe_a_inds2,
                                          [len(self.pe_a_inds2), 1])
        self.pe_a_inds_c2 = numpy.reshape(self.pe_a_inds2,
                                          [1, len(self.pe_a_inds2)])

        self.pe_c_inds2 = range(c_end + self.Na + self.Ns,
                                c_end + self.Na + self.Ns + self.Nc)
        self.pe_c_inds_r2 = numpy.reshape(self.pe_c_inds2,
                                          [len(self.pe_c_inds2), 1])
        self.pe_c_inds_c2 = numpy.reshape(self.pe_c_inds2,
                                          [1, len(self.pe_c_inds2)])

        self.pa_inds2 = range(c_end + self.N, c_end + self.N + self.Na)
        self.pa_inds_r2 = numpy.reshape(self.pa_inds2, [len(self.pa_inds2), 1])
        self.pa_inds_c2 = numpy.reshape(self.pa_inds2, [1, len(self.pa_inds2)])

        self.pc_inds2 = range(c_end + self.N + self.Na,
                              c_end + self.N + self.Na + self.Nc)
        self.pc_inds_r2 = numpy.reshape(self.pc_inds2, [len(self.pc_inds2), 1])
        self.pc_inds_c2 = numpy.reshape(self.pc_inds2, [1, len(self.pc_inds2)])
示例#6
0
 def __init__(self, **kargs):
     Implicit_Problem.__init__(self, **kargs)
     self.name = 'Van der Pol (implicit) with time events'
     self.my = 1.0/1e-6
示例#7
0
 def setup_model(self, y0, yd0, name):
     """
     Setup the Assimulo implicit model to use IDA.
     """
     Implicit_Problem.__init__(self, y0=y0, yd0=yd0, name=name)