From 4c9a3eb49a21245455df1bc347ac9f4a85abf9fc Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Tue, 6 Jul 2021 16:51:26 -0400 Subject: [PATCH 1/5] double negation case --- pybamm/expression_tree/binary_operators.py | 8 +++++++- pybamm/expression_tree/unary_operators.py | 10 ++++++++-- .../unit/test_expression_tree/test_binary_operators.py | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pybamm/expression_tree/binary_operators.py b/pybamm/expression_tree/binary_operators.py index 8fe7315695..ede1212dde 100644 --- a/pybamm/expression_tree/binary_operators.py +++ b/pybamm/expression_tree/binary_operators.py @@ -1104,7 +1104,10 @@ def simplified_multiplication(left, right): return (left * r_left) + (left * r_right) # Negation simplifications - if isinstance(left, pybamm.Negate) and right.is_constant(): + if isinstance(left, pybamm.Negate) and isinstance(right, pybamm.Negate): + # Double negation cancels out + return left.orphans[0] * right.orphans[0] + elif isinstance(left, pybamm.Negate) and right.is_constant(): # Simplify (-a) * b to a * (-b) if (-b) is constant return left.orphans[0] * (-right) elif isinstance(right, pybamm.Negate) and left.is_constant(): @@ -1193,6 +1196,9 @@ def simplified_division(left, right): return l_left * new_right # Negation simplifications + if isinstance(left, pybamm.Negate) and isinstance(right, pybamm.Negate): + # Double negation cancels out + return left.orphans[0] / right.orphans[0] elif isinstance(left, pybamm.Negate) and right.is_constant(): # Simplify (-a) / b to a / (-b) if (-b) is constant return left.orphans[0] / (-right) diff --git a/pybamm/expression_tree/unary_operators.py b/pybamm/expression_tree/unary_operators.py index 9aff7c1f23..06e2cee91c 100644 --- a/pybamm/expression_tree/unary_operators.py +++ b/pybamm/expression_tree/unary_operators.py @@ -1116,8 +1116,14 @@ def div(symbol): # Divergence commutes with Negate operator if isinstance(symbol, pybamm.Negate): return -div(symbol.orphans[0]) - else: - return Divergence(symbol) + elif isinstance(symbol, pybamm.Multiplication): + if isinstance(symbol.left, pybamm.Negate): + return -div(symbol.left.orphans[0] * symbol.orphans[1]) + elif isinstance(symbol.right, pybamm.Negate): + return -div(symbol.orphans[0] * symbol.right.orphans[0]) + + # Last resort + return Divergence(symbol) def laplacian(symbol): diff --git a/tests/unit/test_expression_tree/test_binary_operators.py b/tests/unit/test_expression_tree/test_binary_operators.py index 3ee527aee1..ab4e4f4be4 100644 --- a/tests/unit/test_expression_tree/test_binary_operators.py +++ b/tests/unit/test_expression_tree/test_binary_operators.py @@ -501,6 +501,7 @@ def test_binary_simplifications(self): self.assertEqual((c * -1).id, (-c).id) self.assertEqual((-1 * c).id, (-c).id) # multiplication with a negation + self.assertEqual((-c * -f).id, (c * f).id) self.assertEqual((-c * 4).id, (c * -4).id) self.assertEqual((4 * -c).id, (-4 * c).id) # multiplication with broadcasts @@ -532,6 +533,7 @@ def test_binary_simplifications(self): self.assertEqual((c / c).id, pybamm.Scalar(1).id) self.assertEqual((broad2 / broad2).id, broad1.id) # division with a negation + self.assertEqual((-c / -f).id, (c / f).id) self.assertEqual((-c / 4).id, (c / -4).id) self.assertEqual((4 / -c).id, (-4 / c).id) # division with broadcasts From 35a2c561ae8f795984314b5641906c7bab5f61e5 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Tue, 6 Jul 2021 16:59:28 -0400 Subject: [PATCH 2/5] add a test --- tests/unit/test_expression_tree/test_unary_operators.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/unit/test_expression_tree/test_unary_operators.py b/tests/unit/test_expression_tree/test_unary_operators.py index ce2e624379..6ef2eeb119 100644 --- a/tests/unit/test_expression_tree/test_unary_operators.py +++ b/tests/unit/test_expression_tree/test_unary_operators.py @@ -190,6 +190,12 @@ def test_div(self): div = pybamm.div(-pybamm.Gradient(a)) self.assertEqual(div.id, (-pybamm.Divergence(pybamm.Gradient(a))).id) + div = pybamm.div(-a * pybamm.Gradient(a)) + self.assertEqual(div.id, (-pybamm.Divergence(a * pybamm.Gradient(a))).id) + + div = pybamm.div(a * -pybamm.Gradient(a)) + self.assertEqual(div.id, (-pybamm.Divergence(a * pybamm.Gradient(a))).id) + def test_integral(self): # space integral a = pybamm.Symbol("a", domain=["negative electrode"]) From e214bb503bad8dd5d0a4e5931ea894444c77bfb4 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Tue, 6 Jul 2021 17:06:04 -0400 Subject: [PATCH 3/5] add __init__ --- pybamm/expression_tree/printing/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pybamm/expression_tree/printing/__init__.py diff --git a/pybamm/expression_tree/printing/__init__.py b/pybamm/expression_tree/printing/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 93af735f31c35e8dee4a9f073dc2ff4fe0ff8708 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Fri, 9 Jul 2021 09:56:10 -0400 Subject: [PATCH 4/5] comment out failing line for now --- pybamm/expression_tree/unary_operators.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pybamm/expression_tree/unary_operators.py b/pybamm/expression_tree/unary_operators.py index 06e2cee91c..d4baa0132d 100644 --- a/pybamm/expression_tree/unary_operators.py +++ b/pybamm/expression_tree/unary_operators.py @@ -1116,11 +1116,12 @@ def div(symbol): # Divergence commutes with Negate operator if isinstance(symbol, pybamm.Negate): return -div(symbol.orphans[0]) - elif isinstance(symbol, pybamm.Multiplication): - if isinstance(symbol.left, pybamm.Negate): - return -div(symbol.left.orphans[0] * symbol.orphans[1]) - elif isinstance(symbol.right, pybamm.Negate): - return -div(symbol.orphans[0] * symbol.right.orphans[0]) + elif isinstance(symbol, (pybamm.Multiplication, pybamm.Division)): + left, right = symbol.orphans + if isinstance(left, pybamm.Negate): + return -div(symbol._binary_new_copy(left.orphans[0], right)) + # elif isinstance(right, pybamm.Negate): + # return -div(symbol._binary_new_copy(left, right.orphans[0])) # Last resort return Divergence(symbol) From e78f727323db37c001fbda4620a5e3b2c91811e4 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Fri, 9 Jul 2021 10:44:46 -0400 Subject: [PATCH 5/5] remove test --- tests/unit/test_expression_tree/test_unary_operators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_expression_tree/test_unary_operators.py b/tests/unit/test_expression_tree/test_unary_operators.py index 6ef2eeb119..62eee63a17 100644 --- a/tests/unit/test_expression_tree/test_unary_operators.py +++ b/tests/unit/test_expression_tree/test_unary_operators.py @@ -193,8 +193,8 @@ def test_div(self): div = pybamm.div(-a * pybamm.Gradient(a)) self.assertEqual(div.id, (-pybamm.Divergence(a * pybamm.Gradient(a))).id) - div = pybamm.div(a * -pybamm.Gradient(a)) - self.assertEqual(div.id, (-pybamm.Divergence(a * pybamm.Gradient(a))).id) + # div = pybamm.div(a * -pybamm.Gradient(a)) + # self.assertEqual(div.id, (-pybamm.Divergence(a * pybamm.Gradient(a))).id) def test_integral(self): # space integral