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.
def __init__(self, system, **kwargs): Implicit_Problem.__init__(self, **kwargs) self.name = 'ACAIE problem without concentration checks' self.system = system
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') )
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)
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)])
def __init__(self, **kargs): Implicit_Problem.__init__(self, **kargs) self.name = 'Van der Pol (implicit) with time events' self.my = 1.0/1e-6
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)