Skip to content

Save Jacobian to file - #3464

Open
bendudson wants to merge 10 commits into
nextfrom
save-petsc-jacobian
Open

Save Jacobian to file#3464
bendudson wants to merge 10 commits into
nextfrom
save-petsc-jacobian

Conversation

@bendudson

@bendudson bendudson commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Utilities for saving the solver Jacobian from the SNES and CVODE solvers.

  • PetscPreconditioner saves Jacobian using PETSc binary or ASCII format.
  • Solver saves metadata: A Jacobian global index offset field to the dmp files, and a JSON file with the variable information.
  • SNES and CVODE solvers output Jacobian if save_jacobian = true. An option jacobian_export_kind select whether the Jacobian is calculated using the nonlinear system being solved (that depends on timestep and scaling), the scaled RHS function (that depends on variable scaling), or the raw rhs function is saved.

A python utility read_jacobian.py uses PETSc's PetscBinaryIO.py to read the binary output files. This is used in the integrated tests. In future this utility could be merged into boutdata or xBOUT.

- PetscPreconditioner saves Jacobian using PETSc binary or ASCII
  format.
- Solver saves metadata: A Jacobian global index offset field to
  the dmp files, and a JSON file with the variable information.
- SNES solver outputs Jacobian if `save_jacobian = true`.  An option
  `jacobian_export_kind` select whether the Jacobian is calculated using
  the nonlinear system being solved (that depends on timestep and
  scaling), the scaled RHS function (that depends on variable scaling),
  or the raw `rhs` function is saved.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

Comment thread src/solver/impls/snes/snes.cxx Outdated
.withDefault("jacobian")),
jacobian_export_format((*options)["jacobian_export_format"]
.doc("Format for saved Jacobian matrices: binary, ascii")
.withDefault(PetscMatrixExportFormat::binary)) {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "PetscMatrixExportFormat" is directly included [misc-include-cleaner]

src/solver/impls/snes/snes.cxx:1:

+ #include "bout/petsc_preconditioner.hxx"

Comment thread src/solver/impls/snes/snes.cxx Outdated

PetscErrorCode ComputeJacobianDefaultMaybeExport(SNES snes, Vec x1, Mat Jac, Mat Jac_new,
void* ctx) {
PetscErrorCode err = SNESComputeJacobianDefault(snes, x1, Jac, Jac_new, ctx);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: variable 'err' of type 'PetscErrorCode' (aka 'int') can be declared 'const' [misc-const-correctness]

Suggested change
PetscErrorCode err = SNESComputeJacobianDefault(snes, x1, Jac, Jac_new, ctx);
ctx) {const

Comment thread src/solver/solver.cxx

Field3D Solver::jacobianIndexBase(int localStart) { return globalIndex(localStart); }

std::vector<Solver::JacobianVariableMetadata> Solver::getJacobianMetadata2D() const {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "std::vector" is directly included [misc-include-cleaner]

src/solver/solver.cxx:59:

+ #include <vector>

Saves to same directory as the dmp file outputs,
using `Options::root()["datadir"]`
Started a test to check the output Jacobian

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

}
};

BOUTMAIN(TestSolver);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: variable 'init_err' of type 'int' can be declared 'const' [misc-const-correctness]

BOUTMAIN(TestSolver);
^
Additional context

include/bout/physicsmodel.hxx:430: expanded from macro 'BOUTMAIN'

      int init_err = BoutInitialise(argc, argv);                   \
      ^

Checks that the Jacobian can be read in either sparse or dense format,
and that the values are as expected.
Utility that extracts the block of the Jacobian corresponding
to rows of variable A and columns of variable B.
Adds docstrings and user manual on writing the Jacobian from
SNES and read it into Python.
Documentation includes a table of settings, and examples.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

jacobian_export_format(
(*options)["jacobian_export_format"]
.doc("PETSc MatView format for saved Jacobians: binary or ascii")
.withDefault(PetscMatrixExportFormat::binary)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "PetscMatrixExportFormat" is directly included [misc-include-cleaner]

src/solver/impls/cvode/cvode.cxx:27:

- #include <cstddef>
+ #include "bout/petsc_preconditioner.hxx"
+ #include <cstddef>

#if BOUT_HAS_PETSC
std::string CvodeSolver::getJacobianExportStem(JacobianExportKind kind) {
const std::string datadir = Options::root()["datadir"];
return fmt::format("{}/{}_{}_{:06d}", datadir, jacobian_export_prefix, toString(kind),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "fmt::format" is directly included [misc-include-cleaner]

src/solver/impls/cvode/cvode.cxx:30:

+ #include "fmt/format.h"

jacobian_metadata_written = true;
}

PetscCall(PetscPreconditioner::saveMatrix(jacobian, getJacobianMatrixFilename(stem),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "PetscPreconditioner" is directly included [misc-include-cleaner]

              ^

save_vars(xdata);
PetscCall(VecRestoreArray(x, &xdata));

PetscErrorCode ierr = saveDiagnosticJacobian(JacobianExportKind::rhs, x, t, 0.0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: variable 'ierr' of type 'PetscErrorCode' (aka 'int') can be declared 'const' [misc-const-correctness]

Suggested change
PetscErrorCode ierr = saveDiagnosticJacobian(JacobianExportKind::rhs, x, t, 0.0);
const

if (selected_precon == CvodePreconMethod::Auto) {
if (hasPreconditioner()) {
selected_precon = CvodePreconMethod::user;
} else if (bout::build::has_petsc) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "bout::build::has_petsc" is directly included [misc-include-cleaner]

src/solver/impls/cvode/cvode.cxx:26:

- #include "bout/build_defines.hxx"
+ #include "bout/build_config.hxx"
+ #include "bout/build_defines.hxx"

PetscCall(VecGetArray(f, &fdata));

try {
s->rhs(s->petsc_t, const_cast<BoutReal*>(xdata), s->petsc_rhs_tmp.data(), true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]

{
                         ^

}
};

BOUTMAIN(TestSolver);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: variable 'init_err' of type 'int' can be declared 'const' [misc-const-correctness]

BOUTMAIN(TestSolver);
^
Additional context

include/bout/physicsmodel.hxx:430: expanded from macro 'BOUTMAIN'

      int init_err = BoutInitialise(argc, argv);                   \
      ^

Use of prefix for the metadata file was inconsistent. Since it's
always the same, always use the same name.
@bendudson

Copy link
Copy Markdown
Contributor Author

Formatting errors are from PetscBinaryIO.py that is distributed with PETSc.

@bendudson bendudson changed the title WIP: Save Jacobian to file Save Jacobian to file Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant