Skip to content

Add Implicit Trapezoidal method - #588

Open
Steven-Roberts wants to merge 13 commits into
developfrom
steven/implicit-trapezoidal
Open

Steven-Roberts wants to merge 13 commits into
developfrom
steven/implicit-trapezoidal

Conversation

@Steven-Roberts

@Steven-Roberts Steven-Roberts commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Adds a fixed step implicit trapezoidal method for comparing against adaptive and partitioned integrators. It uses Newton's method with line search for solving nonlinear systems which was found to be key at large time steps.

Proposed changes

  • Adds new VectorHandler operations for norms
  • Removes internal state management from InfNorm which had an initialization bug and instead use new VectorHandler operations
  • Adds ImplicitTrapezoidal class

Checklist

  • All tests pass.
  • Code compiles cleanly with flags -Wall -Wpedantic -Wconversion -Wextra.
  • The new code follows GridKit™ style guidelines.
  • There are unit tests for the new code.
  • The new code is documented.
  • The feature branch is rebased with respect to the target branch.
  • The CHANGELOG.md has been updated to reflect the changes. If this is a minor PR that is part of a larger fix already included in the file, state so.

Further comments

Currently, this is not used outside tests. In a separate PR, we'll need to add support for swapping between IDA, Rosenbrock, and this for phasor dynamics application and other "drivers".

@lukelowry

Copy link
Copy Markdown
Collaborator

Will be invaluable for validating EMT. Important!

Comment thread GridKit/Solver/Dynamic/Native/InfNorm.cpp Outdated
Comment thread GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp Outdated
Comment thread GridKit/LinearAlgebra/Vector/VectorHandlerCpu.cpp
Comment thread GridKit/Solver/Dynamic/Native/RmsNorm.cpp Outdated
Comment on lines +17 to +26
#define BUBBLE_STEP_FAIL(arg) \
do \
{ \
if (int err = (arg)) \
{ \
jacobian_valid_ = false; \
(void) restoreAcceptedState(); \
return err; \
} \
} while (false)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

instead of this scope-guard looking thing, why can't we use something like the experimental scope guards? there are similar things implemented in third-party libraries which could also be used.

Comment on lines +8 to +15
#define BUBBLE_FAIL(arg) \
do \
{ \
if (int err = (arg)) \
{ \
return err; \
} \
} while (false)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this seems indicative of an argument for more use of exceptions to avoid this sort of code being used all over the place. not very relevant to this pr, though, outside of wanting to remove these file-local error handling helpers.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I followed the convention in Rosenbrock.cpp, but I agree exceptions would be more idiomatic than int return values and macros like this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@alexander-novo, could we think of a better way to handle errors?

@Steven-Roberts, how are similar instances handled in SUNDIALS?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@Steven-Roberts, how are similar instances handled in SUNDIALS?

With a similar macro or just writing out the if statement to check the return value. But SUNDIALS does not have access to exceptions, std::expected, and other C++ error handling mechanisms.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@alexander-novo, could we think of a better way to handle errors?

The returning an int for an error code is a very C-like way of handling errors, and using these kind of quality-of-life macros isn't so uncommon in C I think.

A more C++-like approach might be more natural. std::expected or std::variant as suggested by @superwhiskers work very well in Rust, but won't help us with this specific boilerplate issue. Throwing exceptions will reduce the boilerplate heavily, but we'll need to make sure to heavily document which kinds of exceptions can be thrown by functions.

@Steven-Roberts
Steven-Roberts force-pushed the steven/implicit-trapezoidal branch from 39c0ad2 to 9084820 Compare October 6, 2026 18:02
@Steven-Roberts
Steven-Roberts force-pushed the steven/implicit-trapezoidal branch from dc6388d to 646b46c Compare October 13, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants