def test_rhs_set_get(self): model = pybamm.BaseModel() rhs = { pybamm.Symbol("c"): pybamm.Symbol("alpha"), pybamm.Symbol("d"): pybamm.Symbol("beta"), } model.rhs = rhs self.assertEqual(rhs, model.rhs) # test domains rhs = { pybamm.Symbol("c", domain=["negative electrode"]): pybamm.Symbol( "alpha", domain=["negative electrode"] ), pybamm.Symbol("d", domain=["positive electrode"]): pybamm.Symbol( "beta", domain=["positive electrode"] ), } model.rhs = rhs self.assertEqual(rhs, model.rhs) # non-matching domains should fail with self.assertRaises(pybamm.DomainError): model.rhs = { pybamm.Symbol("c", domain=["positive electrode"]): pybamm.Symbol( "alpha", domain=["negative electrode"] ) }
def test_symbol_auxiliary_domains(self): a = pybamm.Symbol( "a", domain="test", auxiliary_domains={"secondary": "sec", "tertiary": "tert"}, ) self.assertEqual(a.domain, ["test"]) self.assertEqual( a.auxiliary_domains, {"secondary": ["sec"], "tertiary": ["tert"]} ) self.assertEqual( a.domains, {"primary": ["test"], "secondary": ["sec"], "tertiary": ["tert"]} ) a = pybamm.Symbol("a", domain=["t", "e", "s"]) self.assertEqual(a.domain, ["t", "e", "s"]) with self.assertRaises(TypeError): a = pybamm.Symbol("a", domain=1) b = pybamm.Symbol("b", domain="test sec") with self.assertRaisesRegex( pybamm.DomainError, "Domain cannot be the same as an auxiliary domain" ): b.auxiliary_domains = {"sec": "test sec"} with self.assertRaisesRegex( pybamm.DomainError, "All auxiliary domains must be different" ): b = pybamm.Symbol( "b", domain="test", auxiliary_domains={"sec": ["test sec"], "tert": ["test sec"]}, )
def test_to_equation(self): a = pybamm.Symbol("a", domain="negative particle") b = pybamm.Symbol("b", domain="current collector") c = pybamm.Symbol("c", domain="test") # Test print_name pybamm.Floor.print_name = "test" self.assertEqual(pybamm.Floor(-2.5).to_equation(), sympy.symbols("test")) # Test Negate self.assertEqual(pybamm.Negate(4).to_equation(), -4.0) # Test AbsoluteValue self.assertEqual(pybamm.AbsoluteValue(-4).to_equation(), 4.0) # Test Gradient self.assertEqual(pybamm.Gradient(a).to_equation(), sympy_Gradient("a")) # Test Divergence self.assertEqual( pybamm.Divergence(pybamm.Gradient(a)).to_equation(), sympy_Divergence(sympy_Gradient(a)), ) # Test BoundaryValue self.assertEqual( pybamm.BoundaryValue(a, "right").to_equation(), sympy.symbols("a^{surf}") ) self.assertEqual( pybamm.BoundaryValue(b, "positive tab").to_equation(), sympy.symbols(str(b)) ) self.assertEqual( pybamm.BoundaryValue(c, "left").to_equation(), sympy.symbols("c^{left}") )
def test_model_dict_behaviour(self): model = pybamm.BaseModel() key = pybamm.Symbol("c") rhs = {key: pybamm.Symbol("alpha")} model.rhs = rhs self.assertEqual(model[key], rhs[key]) self.assertEqual(model[key], model.rhs[key])
def test_base_concatenation(self): a = pybamm.Symbol("a", domain="test a") b = pybamm.Symbol("b", domain="test b") c = pybamm.Symbol("c", domain="test c") conc = pybamm.concatenation(a, b, c) self.assertEqual(conc.name, "concatenation") self.assertEqual(str(conc), "concatenation(a, b, c)") self.assertIsInstance(conc.children[0], pybamm.Symbol) self.assertEqual(conc.children[0].name, "a") self.assertEqual(conc.children[1].name, "b") self.assertEqual(conc.children[2].name, "c") d = pybamm.Vector([2], domain="test a") e = pybamm.Vector([1], domain="test b") f = pybamm.Vector([3], domain="test c") conc2 = pybamm.concatenation(d, e, f) with self.assertRaises(TypeError): conc2.evaluate() # trying to concatenate non-pybamm symbols with self.assertRaises(TypeError): pybamm.concatenation(1, 2) # concatenation of length 0 with self.assertRaisesRegex(ValueError, "Cannot create empty concatenation"): pybamm.concatenation() # concatenation of lenght 1 self.assertEqual(pybamm.concatenation(a), a)
def test_symbol_domains(self): a = pybamm.Symbol("a", domain="test") self.assertEqual(a.domain, ["test"]) a = pybamm.Symbol("a", domain=["t", "e", "s"]) self.assertEqual(a.domain, ["t", "e", "s"]) with self.assertRaises(TypeError): a = pybamm.Symbol("a", domain=1)
def test_broadcast_to_edges(self): a = pybamm.Symbol("a") broad_a = pybamm.PrimaryBroadcastToEdges(a, ["negative electrode"]) self.assertEqual(broad_a.name, "broadcast to edges") self.assertEqual(broad_a.children[0].name, a.name) self.assertEqual(broad_a.domain, ["negative electrode"]) self.assertTrue(broad_a.evaluates_on_edges()) a = pybamm.Symbol( "a", domain=["negative particle"], auxiliary_domains={"secondary": "current collector"}, ) broad_a = pybamm.SecondaryBroadcastToEdges(a, ["negative electrode"]) self.assertEqual(broad_a.domain, ["negative particle"]) self.assertEqual( broad_a.auxiliary_domains, { "secondary": ["negative electrode"], "tertiary": ["current collector"] }, ) self.assertTrue(broad_a.evaluates_on_edges()) a = pybamm.Symbol("a") broad_a = pybamm.FullBroadcastToEdges(a, ["negative electrode"], "current collector") self.assertEqual(broad_a.domain, ["negative electrode"]) self.assertEqual(broad_a.auxiliary_domains["secondary"], ["current collector"]) self.assertTrue(broad_a.evaluates_on_edges())
def test_div(self): # divergence of scalar symbol should fail a = pybamm.Symbol("a") with self.assertRaisesRegex( pybamm.DomainError, "Cannot take divergence of 'a' since its domain is empty", ): pybamm.Divergence(a) # divergence of variable evaluating on edges should fail a = pybamm.PrimaryBroadcast(pybamm.Scalar(1), "test") with self.assertRaisesRegex(TypeError, "evaluates on nodes"): pybamm.Divergence(a) # divergence of broadcast should return broadcasted zero a = pybamm.PrimaryBroadcastToEdges(pybamm.Variable("a"), "test domain") div = pybamm.div(a) self.assertIsInstance(div, pybamm.PrimaryBroadcast) self.assertIsInstance(div.child, pybamm.PrimaryBroadcast) self.assertIsInstance(div.child.child, pybamm.Scalar) self.assertEqual(div.child.child.value, 0) # otherwise divergence should work a = pybamm.Symbol("a", domain="test domain") div = pybamm.Divergence(pybamm.Gradient(a)) self.assertEqual(div.domain, a.domain)
def test_secondary_broadcast(self): a = pybamm.Symbol( "a", domain=["negative particle"], auxiliary_domains={"secondary": "current collector"}, ) broad_a = pybamm.SecondaryBroadcast(a, ["negative electrode"]) self.assertEqual(broad_a.domain, ["negative particle"]) self.assertEqual( broad_a.auxiliary_domains, { "secondary": ["negative electrode"], "tertiary": ["current collector"] }, ) a = pybamm.Symbol("a", domain="negative particle") with self.assertRaisesRegex(pybamm.DomainError, "Secondary broadcast from particle"): pybamm.SecondaryBroadcast(a, "current collector") a = pybamm.Symbol("a", domain="negative electrode") with self.assertRaisesRegex(pybamm.DomainError, "Secondary broadcast from electrode"): pybamm.SecondaryBroadcast(a, "negative particle") a = pybamm.Symbol("a", domain="current collector") with self.assertRaisesRegex(pybamm.DomainError, "Cannot do secondary broadcast"): pybamm.SecondaryBroadcast(a, "electrode")
def test_symbol_diff(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") self.assertIsInstance(a.diff(a), pybamm.Scalar) self.assertEqual(a.diff(a).evaluate(), 1) self.assertIsInstance(a.diff(b), pybamm.Scalar) self.assertEqual(a.diff(b).evaluate(), 0)
def test_gradient(self): # gradient of scalar symbol should fail a = pybamm.Symbol("a") with self.assertRaisesRegex( pybamm.DomainError, "Cannot take gradient of 'a' since its domain is empty"): pybamm.Gradient(a) # gradient of variable evaluating on edges should fail a = pybamm.PrimaryBroadcastToEdges(pybamm.Scalar(1), "test") with self.assertRaisesRegex(TypeError, "evaluates on edges"): pybamm.Gradient(a) # gradient of broadcast should return broadcasted zero a = pybamm.PrimaryBroadcast(pybamm.Variable("a"), "test domain") grad = pybamm.grad(a) self.assertIsInstance(grad, pybamm.PrimaryBroadcastToEdges) self.assertIsInstance(grad.child, pybamm.PrimaryBroadcast) self.assertIsInstance(grad.child.child, pybamm.Scalar) self.assertEqual(grad.child.child.value, 0) # otherwise gradient should work a = pybamm.Symbol("a", domain="test domain") grad = pybamm.Gradient(a) self.assertEqual(grad.children[0].name, a.name) self.assertEqual(grad.domain, a.domain)
def test_upwind_downwind(self): # upwind of scalar symbol should fail a = pybamm.Symbol("a") with self.assertRaisesRegex( pybamm.DomainError, "Cannot upwind 'a' since its domain is empty"): pybamm.Upwind(a) # upwind of variable evaluating on edges should fail a = pybamm.PrimaryBroadcastToEdges(pybamm.Scalar(1), "test") with self.assertRaisesRegex(TypeError, "evaluate on nodes"): pybamm.Upwind(a) # otherwise upwind should work a = pybamm.Symbol("a", domain="test domain") upwind = pybamm.upwind(a) self.assertIsInstance(upwind, pybamm.Upwind) self.assertEqual(upwind.children[0].name, a.name) self.assertEqual(upwind.domain, a.domain) # also test downwind a = pybamm.Symbol("a", domain="test domain") downwind = pybamm.downwind(a) self.assertIsInstance(downwind, pybamm.Downwind) self.assertEqual(downwind.children[0].name, a.name) self.assertEqual(downwind.domain, a.domain)
def test_algebraic_set_get(self): model = pybamm.BaseModel() algebraic = { pybamm.Symbol("b"): pybamm.Symbol("c") - pybamm.Symbol("a") } model.algebraic = algebraic self.assertEqual(algebraic, model.algebraic)
def test_domain_error(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") with self.assertRaisesRegex( pybamm.DomainError, "Cannot concatenate child 'a' with empty domain"): pybamm.DomainConcatenation([a, b], None)
def test_broadcast_to_edges(self): a = pybamm.Symbol("a") # primary broad_a = pybamm.PrimaryBroadcastToEdges(a, ["negative electrode"]) self.assertEqual(broad_a.name, "broadcast to edges") self.assertEqual(broad_a.children[0].name, a.name) self.assertEqual(broad_a.domain, ["negative electrode"]) self.assertTrue(broad_a.evaluates_on_edges("primary")) self.assertFalse(broad_a.broadcasts_to_nodes) self.assertEqual(broad_a.reduce_one_dimension(), a) # secondary a = pybamm.Symbol( "a", domain=["negative particle"], auxiliary_domains={"secondary": "current collector"}, ) broad_a = pybamm.SecondaryBroadcastToEdges(a, ["negative electrode"]) self.assertEqual(broad_a.domain, ["negative particle"]) self.assertEqual( broad_a.auxiliary_domains, { "secondary": ["negative electrode"], "tertiary": ["current collector"] }, ) self.assertTrue(broad_a.evaluates_on_edges("primary")) self.assertFalse(broad_a.broadcasts_to_nodes) # full a = pybamm.Symbol("a") broad_a = pybamm.FullBroadcastToEdges(a, ["negative electrode"], "current collector") self.assertEqual(broad_a.domain, ["negative electrode"]) self.assertEqual(broad_a.auxiliary_domains["secondary"], ["current collector"]) self.assertTrue(broad_a.evaluates_on_edges("primary")) self.assertFalse(broad_a.broadcasts_to_nodes) self.assertEqual( broad_a.reduce_one_dimension().id, pybamm.PrimaryBroadcastToEdges(a, "current collector").id, ) broad_a = pybamm.FullBroadcastToEdges(a, ["negative electrode"], {}) self.assertEqual(broad_a.reduce_one_dimension(), a) broad_a = pybamm.FullBroadcastToEdges( a, "negative particle", { "secondary": "negative electrode", "tertiary": "current collector" }, ) self.assertEqual( broad_a.reduce_one_dimension().id, pybamm.FullBroadcastToEdges(a, "negative electrode", "current collector").id, )
def test_addition(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") summ = pybamm.Addition(a, b) self.assertEqual(summ.children[0].name, a.name) self.assertEqual(summ.children[1].name, b.name) # test simplifying summ2 = pybamm.Scalar(1) + pybamm.Scalar(3) self.assertEqual(summ2.id, pybamm.Scalar(4).id)
def test_concatenation(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") c = pybamm.Symbol("c") # create discretisation disc = get_discretisation_for_testing() conc = disc.concatenate(a, b, c) self.assertIsInstance(conc, pybamm.NumpyConcatenation)
def test_symbol_repr(self): """ test that __repr___ returns the string `__class__(id, name, parent expression)` """ a = pybamm.Symbol("a") b = pybamm.Symbol("b") c = pybamm.Symbol("c", domain=["test"]) d = pybamm.Symbol("d", domain=["test"], auxiliary_domains={"sec": "other test"}) hex_regex = r"\-?0x[0-9,a-f]+" self.assertRegex( a.__repr__(), r"Symbol\(" + hex_regex + r", a, children\=\[\], domain\=\[\], auxiliary_domains\=\{\}\)", ) self.assertRegex( b.__repr__(), r"Symbol\(" + hex_regex + r", b, children\=\[\], domain\=\[\], auxiliary_domains\=\{\}\)", ) self.assertRegex( c.__repr__(), r"Symbol\(" + hex_regex + r", c, children\=\[\], domain\=\['test'\], auxiliary_domains\=\{\}\)", ) self.assertRegex( d.__repr__(), r"Symbol\(" + hex_regex + r", d, children\=\[\], domain\=\['test'\]" + r", auxiliary_domains\=\{'sec': \"\['other test'\]\"\}\)", ) self.assertRegex( (a + b).__repr__(), r"Addition\(" + hex_regex + r", \+, children\=\['a', 'b'\], domain=\[\]", ) self.assertRegex( (c * d).__repr__(), r"Multiplication\(" + hex_regex + r", \*, children\=\['c', 'd'\], domain=\['test'\]" + r", auxiliary_domains\=\{'sec': \"\['other test'\]\"\}\)", ) self.assertRegex( pybamm.grad(a).__repr__(), r"Gradient\(" + hex_regex + r", grad, children\=\['a'\], domain=\[\], auxiliary_domains\=\{\}\)", ) self.assertRegex( pybamm.grad(c).__repr__(), r"Gradient\(" + hex_regex + r", grad, children\=\['c'\], domain=\['test'\]" + r", auxiliary_domains\=\{\}\)", )
def test_binary_operator(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") bin = pybamm.BinaryOperator("binary test", a, b) self.assertEqual(bin.children[0].name, a.name) self.assertEqual(bin.children[1].name, b.name) c = pybamm.Scalar(1) d = pybamm.Scalar(2) bin2 = pybamm.BinaryOperator("binary test", c, d) with self.assertRaises(NotImplementedError): bin2.evaluate()
def test_symbol_methods(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") # unary self.assertIsInstance(-a, pybamm.Negate) self.assertIsInstance(abs(a), pybamm.AbsoluteValue) # special cases neg_a = -a self.assertEqual(-neg_a, a) abs_a = abs(a) self.assertEqual(abs(abs_a), abs_a) # binary - two symbols self.assertIsInstance(a + b, pybamm.Addition) self.assertIsInstance(a - b, pybamm.Subtraction) self.assertIsInstance(a * b, pybamm.Multiplication) self.assertIsInstance(a @ b, pybamm.MatrixMultiplication) self.assertIsInstance(a / b, pybamm.Division) self.assertIsInstance(a**b, pybamm.Power) self.assertIsInstance(a < b, pybamm.Heaviside) self.assertIsInstance(a <= b, pybamm.Heaviside) self.assertIsInstance(a > b, pybamm.Heaviside) self.assertIsInstance(a >= b, pybamm.Heaviside) self.assertIsInstance(a % b, pybamm.Modulo) # binary - symbol and number self.assertIsInstance(a + 2, pybamm.Addition) self.assertIsInstance(a - 2, pybamm.Subtraction) self.assertIsInstance(a * 2, pybamm.Multiplication) self.assertIsInstance(a @ 2, pybamm.MatrixMultiplication) self.assertIsInstance(a / 2, pybamm.Division) self.assertIsInstance(a**2, pybamm.Power) # binary - number and symbol self.assertIsInstance(3 + b, pybamm.Addition) self.assertEqual((3 + b).children[1].id, b.id) self.assertIsInstance(3 - b, pybamm.Subtraction) self.assertEqual((3 - b).children[1].id, b.id) self.assertIsInstance(3 * b, pybamm.Multiplication) self.assertEqual((3 * b).children[1].id, b.id) self.assertIsInstance(3 @ b, pybamm.MatrixMultiplication) self.assertEqual((3 @ b).children[1].id, b.id) self.assertIsInstance(3 / b, pybamm.Division) self.assertEqual((3 / b).children[1].id, b.id) self.assertIsInstance(3**b, pybamm.Power) self.assertEqual((3**b).children[1].id, b.id) # error raising with self.assertRaisesRegex( NotImplementedError, "BinaryOperator not implemented for symbols of type"): a + "two"
def test_power(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") pow1 = pybamm.Power(a, b) self.assertEqual(pow1.name, "**") self.assertEqual(pow1.children[0].name, a.name) self.assertEqual(pow1.children[1].name, b.name) a = pybamm.Scalar(4) b = pybamm.Scalar(2) pow2 = pybamm.Power(a, b) self.assertEqual(pow2.evaluate(), 16)
def test_x_average(self): a = pybamm.Scalar(1) average_a = pybamm.x_average(a) self.assertEqual(average_a.id, a.id) average_broad_a = pybamm.x_average( pybamm.PrimaryBroadcast(a, ["negative electrode"])) self.assertEqual(average_broad_a.evaluate(), np.array([1])) conc_broad = pybamm.Concatenation( pybamm.PrimaryBroadcast(1, ["negative electrode"]), pybamm.PrimaryBroadcast(2, ["separator"]), pybamm.PrimaryBroadcast(3, ["positive electrode"]), ) average_conc_broad = pybamm.x_average(conc_broad) self.assertIsInstance(average_conc_broad, pybamm.Division) for domain in [ ["negative electrode"], ["separator"], ["positive electrode"], ["negative electrode", "separator", "positive electrode"], ]: a = pybamm.Symbol("a", domain=domain) x = pybamm.SpatialVariable("x", domain) av_a = pybamm.x_average(a) self.assertIsInstance(av_a, pybamm.Division) self.assertIsInstance(av_a.children[0], pybamm.Integral) self.assertEqual(av_a.children[0].integration_variable[0].domain, x.domain) self.assertEqual(av_a.domain, []) a = pybamm.Symbol("a", domain="new domain") av_a = pybamm.x_average(a) self.assertEqual(av_a.domain, []) self.assertIsInstance(av_a, pybamm.Division) self.assertIsInstance(av_a.children[0], pybamm.Integral) self.assertEqual(av_a.children[0].integration_variable[0].domain, a.domain) self.assertIsInstance(av_a.children[1], pybamm.Integral) self.assertEqual(av_a.children[1].integration_variable[0].domain, a.domain) self.assertEqual(av_a.children[1].children[0].id, pybamm.ones_like(a).id) # x-average of symbol that evaluates on edges raises error symbol_on_edges = pybamm.PrimaryBroadcastToEdges(1, "domain") with self.assertRaisesRegex( ValueError, "Can't take the x-average of a symbol that evaluates on edges" ): pybamm.x_average(symbol_on_edges)
def test_boundary_value(self): a = pybamm.Scalar(1) boundary_a = pybamm.boundary_value(a, "right") self.assertEqual(boundary_a.id, a.id) boundary_broad_a = pybamm.boundary_value( pybamm.PrimaryBroadcast(a, ["negative electrode"]), "left") self.assertEqual(boundary_broad_a.evaluate(), np.array([1])) a = pybamm.Symbol("a", domain=["separator"]) boundary_a = pybamm.boundary_value(a, "right") self.assertIsInstance(boundary_a, pybamm.BoundaryValue) self.assertEqual(boundary_a.side, "right") self.assertEqual(boundary_a.domain, []) self.assertEqual(boundary_a.auxiliary_domains, {}) # test with secondary domain a_sec = pybamm.Symbol( "a", domain=["separator"], auxiliary_domains={"secondary": "current collector"}, ) boundary_a_sec = pybamm.boundary_value(a_sec, "right") self.assertEqual(boundary_a_sec.domain, ["current collector"]) self.assertEqual(boundary_a_sec.auxiliary_domains, {}) # test with secondary domain and tertiary domain a_tert = pybamm.Symbol( "a", domain=["separator"], auxiliary_domains={ "secondary": "current collector", "tertiary": "bla" }, ) boundary_a_tert = pybamm.boundary_value(a_tert, "right") self.assertEqual(boundary_a_tert.domain, ["current collector"]) self.assertEqual(boundary_a_tert.auxiliary_domains, {"secondary": ["bla"]}) # error if boundary value on tabs and domain is not "current collector" var = pybamm.Variable("var", domain=["negative electrode"]) with self.assertRaisesRegex(pybamm.ModelError, "Can only take boundary"): pybamm.boundary_value(var, "negative tab") pybamm.boundary_value(var, "positive tab") # boundary value of symbol that evaluates on edges raises error symbol_on_edges = pybamm.PrimaryBroadcastToEdges(1, "domain") with self.assertRaisesRegex( ValueError, "Can't take the boundary value of a symbol that evaluates on edges", ): pybamm.boundary_value(symbol_on_edges, "right")
def test_concatenation_domains(self): a = pybamm.Symbol("a", domain=["negative electrode"]) b = pybamm.Symbol("b", domain=["separator", "positive electrode"]) c = pybamm.Symbol("c", domain=["test"]) conc = pybamm.concatenation(a, b, c) self.assertEqual( conc.domain, ["negative electrode", "separator", "positive electrode", "test"], ) # Can't concatenate nodes with overlapping domains d = pybamm.Symbol("d", domain=["separator"]) with self.assertRaises(pybamm.DomainError): pybamm.concatenation(a, b, d)
def test_shape_and_size_for_testing(self): scal = pybamm.Scalar(1) self.assertEqual(scal.shape_for_testing, scal.shape) self.assertEqual(scal.size_for_testing, scal.size) state = pybamm.StateVector(slice(10, 25), domain="test") state2 = pybamm.StateVector(slice(10, 25), domain="test 2") self.assertEqual(state.shape_for_testing, state.shape) param = pybamm.Parameter("a") self.assertEqual(param.shape_for_testing, ()) func = pybamm.FunctionParameter("func", {"state": state}) self.assertEqual(func.shape_for_testing, state.shape_for_testing) concat = pybamm.concatenation(state, state2) self.assertEqual(concat.shape_for_testing, (30, 1)) self.assertEqual(concat.size_for_testing, 30) var = pybamm.Variable("var", domain="negative electrode") broadcast = pybamm.PrimaryBroadcast(0, "negative electrode") self.assertEqual(var.shape_for_testing, broadcast.shape_for_testing) self.assertEqual((var + broadcast).shape_for_testing, broadcast.shape_for_testing) var = pybamm.Variable("var", domain=["random domain", "other domain"]) broadcast = pybamm.PrimaryBroadcast(0, ["random domain", "other domain"]) self.assertEqual(var.shape_for_testing, broadcast.shape_for_testing) self.assertEqual((var + broadcast).shape_for_testing, broadcast.shape_for_testing) sym = pybamm.Symbol("sym") with self.assertRaises(NotImplementedError): sym.shape_for_testing
def test_full_broadcast(self): a = pybamm.Symbol("a") broad_a = pybamm.FullBroadcast(a, ["negative electrode"], "current collector") self.assertEqual(broad_a.domain, ["negative electrode"]) self.assertEqual(broad_a.auxiliary_domains["secondary"], ["current collector"])
def test_function_of_one_variable(self): a = pybamm.Symbol("a") funca = pybamm.Function(test_function, a) self.assertEqual(funca.name, "function (test_function)") self.assertEqual(str(funca), "test_function(a)") self.assertEqual(funca.children[0].name, a.name) b = pybamm.Scalar(1) sina = pybamm.Function(np.sin, b) self.assertEqual(sina.evaluate(), np.sin(1)) self.assertEqual(sina.name, "function ({})".format(np.sin.__name__)) c = pybamm.Vector(np.linspace(0, 1)) cosb = pybamm.Function(np.cos, c) np.testing.assert_array_equal(cosb.evaluate(), np.cos(c.evaluate())) var = pybamm.StateVector(slice(0, 100)) y = np.linspace(0, 1, 100)[:, np.newaxis] logvar = pybamm.Function(np.log1p, var) np.testing.assert_array_equal(logvar.evaluate(y=y), np.log1p(y)) # use known_evals np.testing.assert_array_equal( logvar.evaluate(y=y, known_evals={})[0], np.log1p(y) )
def test_name(self): a = pybamm.Symbol("a") x = np.linspace(0, 1, 200) interp = pybamm.Interpolant(x, x, a, "name") self.assertEqual(interp.name, "name") interp = pybamm.Interpolant(x, x, a) self.assertEqual(interp.name, "interpolating_function")
def test_binary_operator_domains(self): # same domain a = pybamm.Symbol("a", domain=["negative electrode"]) b = pybamm.Symbol("b", domain=["negative electrode"]) bin1 = pybamm.BinaryOperator("binary test", a, b) self.assertEqual(bin1.domain, ["negative electrode"]) # one empty domain c = pybamm.Symbol("c", domain=[]) bin2 = pybamm.BinaryOperator("binary test", a, c) self.assertEqual(bin2.domain, ["negative electrode"]) bin3 = pybamm.BinaryOperator("binary test", c, b) self.assertEqual(bin3.domain, ["negative electrode"]) # mismatched domains d = pybamm.Symbol("d", domain=["positive electrode"]) with self.assertRaises(pybamm.DomainError): pybamm.BinaryOperator("binary test", a, d)
def test_domain_concatenation_domains(self): mesh = get_mesh_for_testing() # ensure concatenated domains are sorted correctly a = pybamm.Symbol("a", domain=["negative electrode"]) b = pybamm.Symbol("b", domain=["separator", "positive electrode"]) c = pybamm.Symbol("c", domain=["negative particle"]) conc = pybamm.DomainConcatenation([c, a, b], mesh) self.assertEqual( conc.domain, [ "negative electrode", "separator", "positive electrode", "negative particle", ], )