Skip to content

Add Rosenbrock integrators#479

Open
alexander-novo wants to merge 56 commits into
alex/linear_solverfrom
alex/rosenbrock
Open

Add Rosenbrock integrators#479
alexander-novo wants to merge 56 commits into
alex/linear_solverfrom
alex/rosenbrock

Conversation

@alexander-novo

@alexander-novo alexander-novo commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Description

Add Rosenbrock integrators, which are lighter-weight alternatives to IDA that work well with co-simulation.

Proposed changes

The current version depends on ReSolve and needs porting work to be used with GridKit vectors. The operations used by the Rosenbrock integrators are:

vector_handler_.scal();
vector_handler_.axpy();
vector_handler_.abs();
vector_handler_.max();
vector_handler_.diagSolve();
vector_handler_.amax();

This PR also need's ReSolve's SystemSolver to be ported.

As well, I think some more testing wouldn't go amiss... An integration test on an example power grid would work nicely.

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.
  • I have updated CHANGELOG.md to reflect the changes in this PR. If this is a minor PR that is part of a larger fix already included in the file, state so.

Further comments

@alexander-novo alexander-novo requested a review from pelesh July 7, 2026 17:42
@alexander-novo alexander-novo self-assigned this Jul 7, 2026
@alexander-novo alexander-novo added the enhancement New feature or request label Jul 7, 2026
@pelesh pelesh added this to the Release 0.2 milestone Jul 8, 2026
@pelesh pelesh mentioned this pull request Jul 8, 2026
7 tasks

@pelesh pelesh left a comment

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 is really nice work!

I would suggest merging #480 first and then rebasing so that we avoid introducing Re::Solve dependency.

Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/RosenbrockTableaus.cpp Outdated
@alexander-novo

Copy link
Copy Markdown
Collaborator Author

@pelesh I've updated the PR to make use of GridKit's own Vector and VectorHandler. Re::Solve is still used for the lienar solver part, however (see Rosenbrock::time_step)

@alexander-novo alexander-novo changed the base branch from develop to slaven/vector-handler July 9, 2026 00:25
@pelesh

pelesh commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

@pelesh I've updated the PR to make use of GridKit's own Vector and VectorHandler. Re::Solve is still used for the lienar solver part, however (see Rosenbrock::time_step)

Using a linear solver from Re::Solve is a good thing :). We can add bare KLU interface in a separate PR, if needed.

@alexander-novo alexander-novo marked this pull request as ready for review July 9, 2026 16:31
@alexander-novo alexander-novo changed the base branch from slaven/vector-handler to develop July 9, 2026 16:32
Comment thread GridKit/Solver/Dynamic/RosenbrockTableaus.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread tests/UnitTests/Solver/Dynamic/RosenbrockTests.hpp

@shakedregev shakedregev left a comment

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.

Fix the minor issues and good to merge. I tested it.

@alexander-novo alexander-novo mentioned this pull request Jul 13, 2026
7 tasks
@alexander-novo alexander-novo changed the base branch from develop to alex/linear_solver July 13, 2026 20:32
@alexander-novo alexander-novo requested a review from pelesh July 13, 2026 20:34

@pelesh pelesh left a comment

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 is very nice work and we can merge it to the feature branch provided the comments below are addressed:

  • Rosenbrock class needs to inherit from DynamicSolver class so it can be called interchangeably with IDA (and I understand there will be some additional work there but we need to open that door now).
  • Files Rosenbrock.*pp should stay in GridKit/Solver/Dynamic directory. For all other files, I suggest moving them to a new directory GridKit/Solver/Dynamic/Rosenbrock.
  • Rosenbrock and related classes should be in AnalysisManager namespace, and the Integrator namespace should be within that to make it consistent with IDA interface.
  • Consider renaming Integrator namespace with something like NativeDynamicSolver or something similar to describe these are solvers native to GridKit, not third party ones (such as SUNDIALS).
  • File ResolveMemoryUtils.hpp should not be needed if the linear solver interface is implemented correctly but we can handle that in #489.
  • A few minor comments below.

Comment thread GridKit/MemoryUtilities/ResolveMemoryUtils.hpp Outdated
Comment thread GridKit/Solver/Dynamic/ErrorNorm.hpp Outdated
Comment on lines +33 to +34
virtual RealT errorNorm(State& err, State& y, State& yprev, GridKit::LinearAlgebra::VectorHandler<ScalarT, IdxT>& handler, GridKit::memory::MemorySpace memspace) const = 0;
};

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.

Why is this pure virtual? Also, have you considered adding errorNorm as a method in Rosenbrock proper?

@alexander-novo alexander-novo Jul 14, 2026

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.

ErrorNorm is just an interface which is implemented by InfNorm. There are different error norms one could want to use. This PR only includes the infinity norm, but the 2 norm is also quite common.

Comment thread GridKit/Solver/Dynamic/AdaptiveStep.hpp Outdated
Comment on lines +20 to +26
struct Parameters
{
/**
* @brief The minimum multiple by which the step size can be multiplied to obtain the new step size.
* Increasing this can allow the integrator to be slightly more conservative in selecting the step size
* - decreasing the number of steps taken but increasing the risk of failing the next step.
*

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.

Do we really need a nested struct in this class? The class itself is small, nesting a structure with 3 real numbers looks like an overkill to me.

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.

The nice thing about having a nested Struct is that it is very easy to set default parameters. The user can create an instance of Parameters with all of the defaults and then change a single one of them with 2 lines of code. But then once the parameters are given to the step controller, they are no longer editable.

To support the same operation with these as normal class members of AdaptiveStep would involve having to write getters/setters for every single one of the parameters.

To me a nested struct isn't "overkill" - it doesn't add any maintenance burden or anything. In my opinion it actually removes maintenance burden in this case.

Comment thread GridKit/Solver/Dynamic/InfNorm.hpp Outdated
Comment thread GridKit/Solver/Dynamic/InfNorm.hpp Outdated
Comment on lines +50 to +65
struct Parameters
{
/**
* @brief A vector of absolute tolerances for each component. The norm will attempt to reject errors
* in each component above this tolerance.
*
*/
std::unique_ptr<State> abs_tol_;

/**
* @brief The relative tolerance. The norm will attempt to reject any error larger in percentage of
* the solution's maximum element than this.
*
*/
RealT rel_tol_;
} params_;

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.

As previously suggested, a nested struct may be an overkill here.

Comment thread GridKit/Solver/Dynamic/Rosenbrock.cpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.hpp Outdated
Comment thread GridKit/Solver/Dynamic/Rosenbrock.hpp Outdated
Comment on lines +30 to +31
class Rosenbrock
{

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.

I think either Rosenbrock or its public interface should inherit from DynamicSolver class. The DynamicSolver should be the one to own the GridKit model.

Comment thread tests/UnitTests/Solver/Dynamic/RosenbrockTests.hpp Outdated
@alexander-novo

Copy link
Copy Markdown
Collaborator Author

@pelesh

I'm not sure what to do about implementing DynamicSolver for Rosenbrock. The method setTolerance doesn't make sense, because the Rosenbrock method doesn't have a tolerance inherently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request new solver

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants