Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds gradient_squared method to FiniteVolume #4540

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
29 changes: 29 additions & 0 deletions src/pybamm/spatial_methods/finite_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,35 @@

return pybamm.Matrix(matrix)

def gradient_squared(self, symbol, discretised_symbol, boundary_conditions):
"""
Computes the square of the gradient of a symbol.

Parameters
----------
symbol : :class:`pybamm.Symbol`
The symbol for which to compute the gradient squared.
discretised_symbol : :class:`pybamm.Vector`
The discretised variable for which to compute the gradient squared.
medha-14 marked this conversation as resolved.
Show resolved Hide resolved
boundary_conditions : dict
Boundary conditions for the symbol.

Returns
-------
float
The gradient squared of the symbol.
"""
domain = symbol.domain
gradient_matrix = self.gradient_matrix(domain, symbol.domains)

Check warning on line 150 in src/pybamm/spatial_methods/finite_volume.py

View check run for this annotation

Codecov / codecov/patch

src/pybamm/spatial_methods/finite_volume.py#L149-L150

Added lines #L149 - L150 were not covered by tests

# Compute gradient squared: (∇u)^2 = u^T (L^T L) u
gradient_squared_matrix = gradient_matrix.T @ gradient_matrix
gradient_squared_result = (

Check warning on line 154 in src/pybamm/spatial_methods/finite_volume.py

View check run for this annotation

Codecov / codecov/patch

src/pybamm/spatial_methods/finite_volume.py#L153-L154

Added lines #L153 - L154 were not covered by tests
discretised_symbol.T @ gradient_squared_matrix @ discretised_symbol
)

return gradient_squared_result.item()

Check warning on line 158 in src/pybamm/spatial_methods/finite_volume.py

View check run for this annotation

Codecov / codecov/patch

src/pybamm/spatial_methods/finite_volume.py#L158

Added line #L158 was not covered by tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, boundary_conditions is mentioned in the function's signature, but it doesn't look like it's used in the logic of the function anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback. I've updated the gradient_squared function to correctly handle boundary conditions, and I've adjusted the tests accordingly to verify these changes.


def divergence(self, symbol, discretised_symbol, boundary_conditions):
"""Matrix-vector multiplication to implement the divergence operator.
See :meth:`pybamm.SpatialMethod.divergence`
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/test_spatial_methods/test_scikit_finite_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,37 @@ def test_gradient(self):
ans = eqn_disc.evaluate(None, 3 * y**2)
np.testing.assert_array_less(0, ans)

def test_gradient_squared(self):
mesh = get_unit_2p1D_mesh_for_testing(ypts=32, zpts=32, include_particles=False)
spatial_methods = {
"macroscale": pybamm.FiniteVolume(),
"current collector": pybamm.ScikitFiniteElement(),
}
disc = pybamm.Discretisation(mesh, spatial_methods)

var = pybamm.Variable("var", domain="current collector")
disc.set_variable_slices([var])

y = mesh["current collector"].coordinates[0, :]
z = mesh["current collector"].coordinates[1, :]

gradient = pybamm.grad(var)
grad_disc = disc.process_symbol(gradient)
grad_disc_y, grad_disc_z = grad_disc.children

gradient_squared = pybamm.grad_squared(var)
gradient_squared_disc = disc.process_symbol(gradient_squared)

inner_product_y = grad_disc_y.evaluate(None, 5 * y + 6 * z)
inner_product_z = grad_disc_z.evaluate(None, 5 * y + 6 * z)
inner_product = inner_product_y**2 + inner_product_z**2

grad_squared_result = gradient_squared_disc.evaluate(None, 5 * y + 6 * z)

np.testing.assert_array_almost_equal(grad_squared_result, inner_product)

np.testing.assert_array_less(0, grad_squared_result)

def test_manufactured_solution(self):
mesh = get_unit_2p1D_mesh_for_testing(ypts=32, zpts=32, include_particles=False)
spatial_methods = {
Expand Down
Loading