Skip to content

Commit 7ccb364

Browse files
authored
fix 2d inner product (#5175)
* fix 2d inner product * improve coverage
1 parent 5e6cbc5 commit 7ccb364

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

src/pybamm/spatial_methods/finite_volume_2d.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,29 @@ def evaluate_at(self, symbol, discretised_child, position):
17531753
"""
17541754
raise NotImplementedError
17551755

1756+
def _inner(self, left, right, disc_left, disc_right):
1757+
# 1) Ensure both operands are vector fields; if not, treat scalar as same in both directions
1758+
if not hasattr(disc_left, "lr_field") or not hasattr(disc_left, "tb_field"):
1759+
disc_left = pybamm.VectorField(disc_left, disc_left)
1760+
if not hasattr(disc_right, "lr_field") or not hasattr(disc_right, "tb_field"):
1761+
disc_right = pybamm.VectorField(disc_right, disc_right)
1762+
1763+
# 2) Broadcast components back to nodes (convert edge-evaluated to node-evaluated)
1764+
# Left-right components
1765+
left_lr = disc_left.lr_field
1766+
right_lr = disc_right.lr_field
1767+
left_tb = disc_left.tb_field
1768+
right_tb = disc_right.tb_field
1769+
if left.evaluates_on_edges("primary"):
1770+
left_lr = self.edge_to_node(left_lr, method="arithmetic", direction="lr")
1771+
left_tb = self.edge_to_node(left_tb, method="arithmetic", direction="tb")
1772+
if right.evaluates_on_edges("primary"):
1773+
right_lr = self.edge_to_node(right_lr, method="arithmetic", direction="lr")
1774+
right_tb = self.edge_to_node(right_tb, method="arithmetic", direction="tb")
1775+
# 3) Multiply corresponding components and sum
1776+
out = pybamm.simplify_if_constant(left_lr * right_lr + left_tb * right_tb)
1777+
return out
1778+
17561779
def process_binary_operators(self, bin_op, left, right, disc_left, disc_right):
17571780
"""Discretise binary operators in model equations. Performs appropriate
17581781
averaging of diffusivities if one of the children is a gradient operator, so
@@ -1810,6 +1833,10 @@ def process_binary_operators(self, bin_op, left, right, disc_left, disc_right):
18101833
left_evaluates_on_edges = left.evaluates_on_edges("primary")
18111834
right_evaluates_on_edges = right.evaluates_on_edges("primary")
18121835

1836+
# inner product takes fluxes from edges to nodes
1837+
if isinstance(bin_op, pybamm.Inner):
1838+
return self._inner(left, right, disc_left, disc_right)
1839+
18131840
# This could be cleaned up a bit, but it works for now.
18141841
if hasattr(disc_left, "lr_field") and hasattr(disc_right, "lr_field"):
18151842
if right_evaluates_on_edges and not left_evaluates_on_edges:
@@ -1916,16 +1943,10 @@ def process_binary_operators(self, bin_op, left, right, disc_left, disc_right):
19161943
return pybamm.VectorField(lr_field, tb_field)
19171944
else:
19181945
pass
1919-
# inner product takes fluxes from edges to nodes
1920-
if isinstance(bin_op, pybamm.Inner):
1921-
if left_evaluates_on_edges:
1922-
disc_left = self.edge_to_node(disc_left)
1923-
if right_evaluates_on_edges:
1924-
disc_right = self.edge_to_node(disc_right)
19251946

19261947
# If neither child evaluates on edges, or both children have gradients,
19271948
# no need to do any averaging
1928-
elif left_evaluates_on_edges == right_evaluates_on_edges:
1949+
if left_evaluates_on_edges == right_evaluates_on_edges:
19291950
pass
19301951
# If only left child evaluates on edges, map right child onto edges
19311952
# using the harmonic mean if the left child is a gradient (i.e. this

tests/unit/test_spatial_methods/test_finite_volume_2d/test_finite_volume_2d.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ def test_process_binary_operators(self):
242242
pybamm.div(2 * pybamm.grad(var)) + 3 * var,
243243
-2 * pybamm.div(var * pybamm.grad(var) + 2 * pybamm.grad(var)),
244244
pybamm.laplacian(var),
245-
pybamm.Inner(pybamm.Magnitude(pybamm.grad(var), "lr"), var),
246-
pybamm.Inner(var, pybamm.Magnitude(pybamm.grad(var), "lr")),
245+
pybamm.Inner(pybamm.grad(var), var),
246+
pybamm.Inner(var, pybamm.grad(var)),
247247
]:
248248
# Check that the equation can be evaluated for different combinations
249249
# of boundary conditions

0 commit comments

Comments
 (0)