@@ -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
0 commit comments