Skip to content

Bug: Configuring sparse Jacobians with IDA assumes Jacobian has been evaluated already #282

@alexander-novo

Description

@alexander-novo

Description how to reproduce the bug

Design a simulation which uses sparse Jacobians and does not evaluate the Jacobian before running the simulation (for an example of such a simulation, see this Microgrid benchmark). The Jacobian will not be calculated correctly, and the linear solver in SUNDIALS will error, complaining about being configured incorrectly.

GridKit™ version

develop

System and environment details

N/A

Additional information

The reason for the bug is simple:

This commit changed the sparse linear solver configuration code in ida.cpp to no longer assume that there were n^2 non-zero elements in the jacobian. To do that, it calls (model_->getJacobian()).nnz() but getJacobian() must be called only after calling evaluateJacobian() (un-documented, but true).

The reason that this wasn't caught is because currently, the only simulations we have being tested using sparse Jacobians coincidentally all evaluate their Jacobian before running the simulation:

But...

  1. This shouldn't be a necessary step.
  2. Evaluating Jacobians before configuring the simulation isn't even enough - some (potentially) nonzero elements are squashed during Jacobian evaluation if the alpha coefficient is set to 0, which it often is if updateTime() hasn't also been called beforehand.
  3. The number of nonzero elements should probably be allowed to change during simulations - discrete events like faults can introduce new variables into the system.

Luckily, SUNDIALS has an interface for re-allocating sparse matrices, which we can call after evaluating the system Jacobian and realising there isn't enough space.

So the correct steps should probably be something along the lines of:

  1. When configuring the linear solver, allocate a small (maybe 0 sized if SUNDIALS lets us) jacobian matrix, and keep track of how much space it has for nonzero elements
  2. After evaluating a system jacobian, compare the number of nonzero elements it has and how much space the SUNDIALS matrix has - if they differ, then re-allocate the SUNDIALS matrix to fit
  3. Finally, copy the entries from the system Jacobian to the SUNDIALS matrix.

Eventually, the GridKit CSR matrix interface should also be able to handle this re-allocation automatically, without having to copy between two buffers.

Metadata

Metadata

Labels

bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions