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

Improve consistent initialization speed and robustness #4301

Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

- Added additional user-configurable options to the (`IDAKLUSolver`) and adjusted the default values to improve performance. ([#4282](https://github.com/pybamm-team/PyBaMM/pull/4282))

## Optimizations

- Improved performance and reliability of DAE consistent initialization. ([#4301](https://github.com/pybamm-team/PyBaMM/pull/4301))
## Bug Fixes

- Fixed bug where IDAKLU solver failed when `output variables` were specified and an event triggered. ([#4300](https://github.com/pybamm-team/PyBaMM/pull/4300))
Expand Down
21 changes: 11 additions & 10 deletions docs/source/examples/notebooks/solvers/dae-solver.ipynb

Large diffs are not rendered by default.

39 changes: 20 additions & 19 deletions pybamm/discretisations/discretisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@


def has_bc_of_form(symbol, side, bcs, form):
if symbol in bcs:
if bcs[symbol][side][1] == form:
return True
else:
return False

else:
return False
return (symbol in bcs) and (bcs[symbol][side][1] == form)


class Discretisation:
Expand Down Expand Up @@ -614,27 +607,28 @@ def create_mass_matrix(self, model):
for var in sorted_model_variables:
if var.domain == []:
# If variable domain empty then mass matrix is just 1
mass_list.append(1.0)
mass_inv_list.append(1.0)
mass = 1.0
mass_inv = 1.0
else:
mass = (
self.spatial_methods[var.domain[0]]
.mass_matrix(var, self.bcs)
.entries
)
mass_list.append(mass)
if isinstance(
self.spatial_methods[var.domain[0]],
(pybamm.ZeroDimensionalSpatialMethod, pybamm.FiniteVolume),
):
# for 0D methods the mass matrix is just a scalar 1 and for
# finite volumes the mass matrix is identity, so no need to
# compute the inverse
mass_inv_list.append(mass)
mass_inv = mass
else:
# inverse is more efficient in csc format
mass_inv = inv(csc_matrix(mass))
mass_inv_list.append(mass_inv)

mass_list.append(mass)
mass_inv_list.append(mass_inv)

# Create lumped mass matrix (of zeros) of the correct shape for the
# discretised algebraic equations
Expand All @@ -645,14 +639,21 @@ def create_mass_matrix(self, model):

# Create block diagonal (sparse) mass matrix (if model is not empty)
# and inverse (if model has odes)
if len(model.rhs) + len(model.algebraic) > 0:
N_rhs = len(model.rhs)
N_alg = len(model.algebraic)

has_mass_matrix = N_rhs > 0 or N_alg > 0
has_mass_matrix_inv = N_rhs > 0

if has_mass_matrix:
mass_matrix = pybamm.Matrix(block_diag(mass_list, format="csr"))
if len(model.rhs) > 0:
mass_matrix_inv = pybamm.Matrix(block_diag(mass_inv_list, format="csr"))
else:
mass_matrix_inv = None
else:
mass_matrix, mass_matrix_inv = None, None
mass_matrix = None

if has_mass_matrix_inv:
mass_matrix_inv = pybamm.Matrix(block_diag(mass_inv_list, format="csr"))
else:
mass_matrix_inv = None

return mass_matrix, mass_matrix_inv

Expand Down
Loading
Loading