C Module: svIntegratorAdaptiveRungeKutta

svIntegratorAdaptiveRungeKutta<numberStages> extends the fixed RK machinery with an embedded lower/higher-order pair and internal step-size control. The inherited bArray forms the lower-order candidate; bStarArray forms the higher-order candidate accepted when the scaled error is at most one.

The integrator covers one requested interval through accepted internal substeps. Its inherited base buffer tracks the latest accepted substep, while entryState preserves the beginning of the requested interval for exception rollback. Nonfinite results and a step size too small to advance representable time raise errors rather than continuing indefinitely.

Relative and absolute tolerances resolve independently in this order:

  1. An override for a particular dynamics object and state name.

  2. An override for the state name across synchronized objects.

  3. The global default.

Resolved ToleranceSpan entries follow descriptor order. Configuration revisions and snapshots of the legacy public defaults determine when they must be refreshed. Whole-state control uses the norm of the stored-state error; per-component control uses scalar errors. A special update policy does not supply a separate error metric. See Dynamics state and integrator architecture for the scaling equations and buffer relationships.


Embedded RK error control and cached state tolerance configuration.

class StateVecAdaptiveIntegrator
#include <svIntegratorAdaptiveRungeKutta.h>

Interface for integrators that support state-specific adaptive tolerances.

This non-templated interface lets callers configure per-state tolerances without needing to know the concrete Runge-Kutta stage count.

Subclassed by svIntegratorAdaptiveRungeKutta< numberStages >

Public Functions

virtual ~StateVecAdaptiveIntegrator() = default
virtual void setRelativeTolerance(std::string stateName, double relTol) = 0

Sets the relative tolerance for the state identified by the given name.

virtual void setAbsoluteTolerance(std::string stateName, double absTol) = 0

Sets the absolute tolerance for the state identified by the given name.

template<size_t numberStages>
struct RKAdaptiveCoefficients : public RKCoefficients<numberStages>
#include <svIntegratorAdaptiveRungeKutta.h>

Extends RKCoefficients with weights for the higher-order member of an embedded pair. The inherited bArray contains the lower-order weights.

The extended Butcher table looks like:

c | A

b

b*

Public Members

RKCoefficients<numberStages>::StageSizedArray bStarArray = {}

“b*” Coefficients of the Adaptive RK method (“b” coefficients of the higher order method)

template<size_t numberStages>
class svIntegratorAdaptiveRungeKutta : public svIntegratorRungeKutta<numberStages>, public StateVecAdaptiveIntegrator
#include <svIntegratorAdaptiveRungeKutta.h>

Explicit embedded RK integration with internal error-controlled substeps.

integrateImpl() covers the entire requested interval, accepting the higher-order candidate or reducing the internal step when its error ratio exceeds one. The inherited baseState tracks accepted substeps; entryState preserves the start of the requested interval for exception rollback.

Tolerances resolve independently from object-and-state overrides, state-name defaults, then global defaults. Cached descriptor-aligned spans avoid map lookups during error evaluation. ErrorControlMode selects a whole-state norm or individual scalar thresholds, including for states with special update policies.

Public Functions

svIntegratorAdaptiveRungeKutta(DynamicObject *dynIn, const RKAdaptiveCoefficients<numberStages> &coefficients, const double methodLargestOrder)

Constructs the integrator for the given dynamic object and specified Adaptive RK coefficients.

methodLargestOrder is the higher order of the two orders used in adaptive RK methods. For the RKF45 method, for example, methodLargestOrder should be 5.

void setRelativeTolerance(double relTol)

Sets the relative tolerance for every DynamicObject and every state.

This is akin to changing svIntegratorAdaptiveRungeKutta::relTol directly

double getRelativeTolerance()

Returns the relative tolerance for every DynamicObject and every state.

This is akin to reading svIntegratorAdaptiveRungeKutta::relTol directly

void setAbsoluteTolerance(double absTol)

Sets the absolute tolerance for every DynamicObject and every state.

This is akin to changing svIntegratorAdaptiveRungeKutta::absTol directly

double getAbsoluteTolerance()

Returns the absolute tolerance for every DynamicObject and every state.

This is akin to reading svIntegratorAdaptiveRungeKutta::absTol directly

virtual void setRelativeTolerance(std::string stateName, double relTol) override

Sets the relative tolerance for every DynamicObject and the state identified by the given name.

std::optional<double> getRelativeTolerance(std::string stateName)

Returns the relative tolerance for every DynamicObject and the state identified by the given name.

If the relative tolerance for this state was not set, then returns an empty optional.

virtual void setAbsoluteTolerance(std::string stateName, double absTol) override

Sets the absolute tolerance for every DynamicObject and the state identified by the given name.

std::optional<double> getAbsoluteTolerance(std::string stateName)

Returns the absolute tolerance for every DynamicObject and the state identified by the given name.

If the absolute tolerance for this state was not set, then returns an empty optional.

void setRelativeTolerance(const DynamicObject &dynamicObject, std::string stateName, double relTol)

Sets the relative tolerance for the given DynamicObject and the state identified by the given name.

inline std::optional<double> getRelativeTolerance(const DynamicObject &dynamicObject, std::string stateName)

Returns the relative tolerance for the given DynamicObject and the state identified by the given name.

If the relative tolerance for this state and DynamicObject was not set, then returns an empty optional.

void setAbsoluteTolerance(const DynamicObject &dynamicObject, std::string stateName, double absTol)

Sets the absolute tolerance for the given DynamicObject and the state identified by the given name.

inline std::optional<double> getAbsoluteTolerance(const DynamicObject &dynamicObject, std::string stateName)

Returns the absolute tolerance for the given DynamicObject and the state identified by the given name.

If the absolute tolerance for this state and DynamicObject was not set, then returns an empty optional.

Public Members

double relTol = 1e-4

Maximum relative truncation error allowed.

The relative truncation error is the absolute error of the state divided by the magnitude of the state.

double absTol = 1e-8

Maximum absolute truncation error allowed.

double safetyFactorForNextStepSize = 0.9

When a new step size is computed, it is multiplied by this factor.

A factor below one reduces the predicted step size to leave room for error-estimate uncertainty. This can reduce rejected trials but does not guarantee acceptance.

double maximumFactorIncreaseForNextStepSize = 4.0

When a new step size is computed, it can only be maximumFactorIncreaseForNextStepSize times the old step size.

double minimumFactorDecreaseForNextStepSize = 0.1

When a new step size is computed, it must be above minimumFactorDecreaseForNextStepSize times the old step size.

Protected Types

using StateToleranceOverrides = std::unordered_map<std::string, ToleranceOverride>

Configuration indexed by registration name; resolved outside stage loops.

Protected Functions

virtual void integrateImpl(double currentTime, double timeStep) override

Performs the integration of the associated dynamic objects up to time currentTime+timeStep

virtual void prepareIntegrationBinding() override

Prepare RK stages, interval rollback, embedded candidates, and tolerance spans.

const DynamicObject *requireDynamicObject(const DynamicObject &dynamicObject) const

Validates that a DynamicObject is propagated by this integrator.

double computeFlatMaxRelativeError()

Compute the largest error-to-tolerance ratio from embedded candidates. Uses high-minus-low error scaled by absolute + relative * magnitude(high). Whole-state scaling uses matrix norms; per-component scaling uses scalar magnitudes.

Returns:

Maximum ratio; a trial is acceptable when this is at most one.

void resolveToleranceSpans(bool force = false)

Refresh descriptor-aligned tolerances after configuration or binding changes.

Parameters:

force – Rebuild even with unchanged tolerances when state descriptors have changed.

Protected Attributes

const double methodLargestOrder

The higher order of the two orders used in adaptive RK methods.

For the RKF45 method, for example, methodLargestOrder should be 5.

const RKCoefficients<numberStages>::StageSizedArray bStarArray

Higher-order candidate weights.

StateToleranceOverrides stateToleranceOverrides

State-name defaults shared by every synchronized dynamic object.

std::unordered_map<const DynamicObject*, StateToleranceOverrides> objectToleranceOverrides

Dynamic-object-specific state tolerance overrides.

Eigen::VectorXd entryState

Full-interval rollback, independent of accepted internal substeps.

Eigen::VectorXd lowOrderState

Embedded lower-order trial candidate.

Eigen::VectorXd highOrderState

Embedded higher-order trial, swapped into baseState on acceptance.

std::vector<ToleranceSpan> toleranceSpans

Resolved metadata in flat state order.

uint64_t toleranceConfigurationGeneration = 0

Advances when a tolerance setter changes configuration.

uint64_t resolvedToleranceConfigurationGeneration = std::numeric_limits<uint64_t>::max()

Cached revision.

double resolvedRelativeTolerance = std::numeric_limits<double>::quiet_NaN()

Detects direct relTol writes.

double resolvedAbsoluteTolerance = std::numeric_limits<double>::quiet_NaN()

Detects direct absTol writes.

Protected Static Functions

static void validateTolerance(double tolerance, const char *toleranceName)

Rejects invalid tolerance values before they enter error scaling.

struct ToleranceSpan
#include <svIntegratorAdaptiveRungeKutta.h>

Resolved tolerance and shape for one flat state, with no name lookup at use.

Public Members

size_t globalStateOffset

First scalar in a combined state buffer.

Eigen::Index rows

Rows in this state’s matrix.

Eigen::Index columns

Columns in this state’s matrix.

double relative

Dimensionless resolved relative tolerance.

double absolute

Resolved absolute tolerance, in the state’s units.

ErrorControlMode mode

Whole-state norm or per-component scaling.

struct ToleranceOverride
#include <svIntegratorAdaptiveRungeKutta.h>

Independently optional overrides; absent values inherit the next default.

Public Members

std::optional<double> relative

Optional dimensionless relative tolerance.

std::optional<double> absolute

Optional absolute tolerance in the state’s units.