Simbody
3.7
|
An Integrator is an object that can advance the State of a System through time. More...
Public Types | |
enum | SuccessfulStepStatus { ReachedReportTime =1, ReachedEventTrigger =2, ReachedScheduledEvent =3, TimeHasAdvanced =4, ReachedStepLimit =5, EndOfSimulation =6, StartOfContinuousInterval =7, InvalidSuccessfulStepStatus = -1 } |
When a step is successful, it will return an indication of what caused it to stop where it did. More... | |
enum | TerminationReason { ReachedFinalTime = 1, AnUnrecoverableErrorOccurred = 2, EventHandlerRequestedTermination = 3, InvalidTerminationReason = -1 } |
Once the simulation has ended, getTerminationReason() may be called to find out what caused it to end. More... | |
Public Member Functions | |
Integrator () | |
~Integrator () | |
const char * | getMethodName () const |
Get the name of this integration method. More... | |
int | getMethodMinOrder () const |
Get the minimum order this Integrator may use. More... | |
int | getMethodMaxOrder () const |
Get the maximum order this Integrator may use. More... | |
bool | methodHasErrorControl () const |
Get whether this Integrator provides error control. More... | |
void | initialize (const State &state) |
Supply the integrator with a starting state. More... | |
void | reinitialize (Stage stage, bool shouldTerminate) |
After an event handler has made a discontinuous change to the Integrator's "advanced state", this method must be called to reinitialize the Integrator. More... | |
const State & | getState () const |
Return a State corresponding to the "current" time at the end of the last call to stepTo() or stepBy(). More... | |
Real | getTime () const |
Get the time of the current State. This is equivalent to calling getState().getTime(). More... | |
bool | isStateInterpolated () const |
Get whether getState() will return an interpolated state or just the same thing as getAdvancedState() does. More... | |
const State & | getAdvancedState () const |
Return the state representing the trajectory point to which the integrator has irreversibly advanced. More... | |
Real | getAdvancedTime () const |
Get the time of the advanced State. This is equivalent to calling getAdvancedState().getTime(). More... | |
State & | updAdvancedState () |
Get a non-const reference to the advanced state. More... | |
Real | getAccuracyInUse () const |
Get the accuracy which is being used for error control. More... | |
Real | getConstraintToleranceInUse () const |
Get the constraint tolerance which is being used for error control. More... | |
SuccessfulStepStatus | stepTo (Real reportTime, Real scheduledEventTime=Infinity) |
Integrate the System until something happens which requires outside processing, and return a status code describing what happened. More... | |
SuccessfulStepStatus | stepBy (Real interval, Real scheduledEventTime=Infinity) |
Integrate the System until something happens which requires outside processing, and return a status code describing what happened. More... | |
Vec2 | getEventWindow () const |
Get the window (tLow, tHigh] within which one or more events have been localized. More... | |
const Array_< EventId > & | getTriggeredEvents () const |
Get the IDs of all events which have been localized within the event window. More... | |
const Array_< Real > & | getEstimatedEventTimes () const |
Get the estimated times of all events which have been localized within the event window. More... | |
const Array_< Event::Trigger > & | getEventTransitionsSeen () const |
Get EventTriggers describing the events which have been localized within the event window. More... | |
bool | isSimulationOver () const |
Get whether the simulation has terminated. More... | |
TerminationReason | getTerminationReason () const |
Get the reason the simulation terminated. More... | |
void | resetAllStatistics () |
Reset all statistics to zero. More... | |
Real | getActualInitialStepSizeTaken () const |
Get the size of the first successful step after the last initialize() call. More... | |
Real | getPreviousStepSizeTaken () const |
Get the size of the most recent successful step. More... | |
Real | getPredictedNextStepSize () const |
Get the step size that will be attempted first on the next call to stepTo() or stepBy(). More... | |
int | getNumStepsAttempted () const |
Get the total number of steps that have been attempted (successfully or unsuccessfully) since the last call to resetAllStatistics(). More... | |
int | getNumStepsTaken () const |
Get the total number of steps that have been successfully taken since the last call to resetAllStatistics(). More... | |
int | getNumRealizations () const |
Get the total number of state realizations that have been performed since the last call to resetAllStatistics(). More... | |
int | getNumQProjections () const |
Get the total number of times a state positions Q have been projected since the last call to resetAllStatistics(). More... | |
int | getNumUProjections () const |
Get the total number of times a state velocities U have been projected since the last call to resetAllStatistics(). More... | |
int | getNumProjections () const |
Get the total number of times a state has been projected (counting both Q and U projections) since the last call to resetAllStatistics(). More... | |
int | getNumErrorTestFailures () const |
Get the number of attempted steps that have failed due to the error being unacceptably high since the last call to resetAllStatistics(). More... | |
int | getNumConvergenceTestFailures () const |
Get the number of attempted steps that failed due to non-convergence of internal step iterations. More... | |
int | getNumRealizationFailures () const |
Get the number of attempted steps that have failed due to an error when realizing the state since the last call to resetAllStatistics(). More... | |
int | getNumQProjectionFailures () const |
Get the number of attempted steps that have failed due to an error when projecting the state positions (Q) since the last call to resetAllStatistics(). More... | |
int | getNumUProjectionFailures () const |
Get the number of attempted steps that have failed due to an error when projecting the state velocities (U) since the last call to resetAllStatistics(). More... | |
int | getNumProjectionFailures () const |
Get the number of attempted steps that have failed due to an error when projecting the state (either a Q- or U-projection) since the last call to resetAllStatistics(). More... | |
int | getNumConvergentIterations () const |
For iterative methods, get the number of internal step iterations in steps that led to convergence (not necessarily successful steps). More... | |
int | getNumDivergentIterations () const |
For iterative methods, get the number of internal step iterations in steps that did not lead to convergence. More... | |
int | getNumIterations () const |
For iterative methods, this is the total number of internal step iterations taken regardless of whether those iterations led to convergence or to successful steps. More... | |
void | setFinalTime (Real tFinal) |
Set the time at which the simulation should end. More... | |
void | setInitialStepSize (Real hinit) |
Set the initial step size that should be attempted. More... | |
void | setMinimumStepSize (Real hmin) |
Set the minimum step size that should ever be used. More... | |
void | setMaximumStepSize (Real hmax) |
Set the maximum step size that should ever be used. More... | |
void | setFixedStepSize (Real stepSize) |
Set the integrator to use a single fixed step size for all steps. More... | |
void | setAccuracy (Real accuracy) |
Set the overall accuracy that should be used for integration. More... | |
void | setConstraintTolerance (Real consTol) |
Set the tolerance within which constraints must be satisfied. More... | |
void | setUseInfinityNorm (bool useInfinityNorm) |
(Advanced) Use infinity norm (maximum absolute value) instead of default RMS norm to evaluate whether accuracy has been achieved for states and for constraint tolerance. More... | |
bool | isInfinityNormInUse () const |
(Advanced) Are we currently using the infinity norm? More... | |
void | setInternalStepLimit (int nSteps) |
Set the maximum number of steps that may be taken within a single call to stepTo() or stepBy(). More... | |
void | setReturnEveryInternalStep (bool shouldReturn) |
Set whether the Integrator should return from stepTo() or stepBy() after every internal step, even if no event has occurred and the report time has not been reached. More... | |
void | setProjectEveryStep (bool forceProject) |
Set whether the system should be projected back to the constraint manifold after every step. More... | |
void | setAllowInterpolation (bool shouldInterpolate) |
Set whether the Integrator is permitted to return interpolated states for reporting purposes which may be less accurate than the "real" states that form the trajectory. More... | |
void | setProjectInterpolatedStates (bool shouldProject) |
Set whether interpolated states should be projected back to the constraint manifold after interpolation is performed. More... | |
void | setForceFullNewton (bool forceFullNewton) |
(Advanced) Constraint projection may use an out-of-date iteration matrix for efficiency. More... | |
Static Public Member Functions | |
static String | getSuccessfulStepStatusString (SuccessfulStepStatus) |
Get a human readable description of the reason a step returned. More... | |
static String | getTerminationReasonString (TerminationReason) |
Get a human readable description of the termination reason. More... | |
static String | successfulStepStatusString (SuccessfulStepStatus stat) |
OBSOLETE: use getSuccessfulStepStatusString(). More... | |
Protected Member Functions | |
const IntegratorRep & | getRep () const |
IntegratorRep & | updRep () |
Protected Attributes | |
IntegratorRep * | rep |
Friends | |
class | IntegratorRep |
An Integrator is an object that can advance the State of a System through time.
This is an abstract class. Subclasses implement a variety of different integration methods, which vary in their speed, accuracy, stability, and various other properties.
An Integrator is most often used in combination with a TimeStepper. The TimeStepper automates much of the work of using an Integrator: invoking it repeatedly to advance time, calling event handlers, reinitializing the Integrator as necessary, and so on. A typical use of an Integrator generally resembles the following:
Given a continuous system of differential equations for state variables y, and optionally a manifold (set of algebraic equations) on which the solution must lie, an Integrator object will advance that system through time. If the full system is continuous, this is sufficient. However, most interesting systems consist of both continuous and discrete equations, in which case the overall time advancement is handled by a TimeStepper object which will use an Integrator as an "inner loop" for advancing the system across continuous intervals between discrete updates. In that case, in addition to continuous state variables y there will be a set of discrete variables d which are held constant during an integration interval.
The continuous part of the system is an ODE-on-a-manifold system suitable for solution via coordinate projection[1], structured like this: (1) y' = f(d;t,y) differential equations (2) 0 = c(d;t,y) algebraic equations (manifold is c=0) (3) e = e(d;t,y) event triggers (watch for zero crossings) with initial conditions t0,y0 such that c=0. The "d;" is a reminder that the overall system is dependent on discrete variables d as well as y, but d cannot change during a continuous interval.
By "ODE on a manifold" we mean that the ODE (1) automatically satisfies the condition that IF c==0, THEN c'=0, where c'=partial(c)/partial(t) + [partial(c)/partial(y)]*y'. This is a less stringent condition than an ODE with "first integral" invariant, in which c'=0 regardless of whether c=0.
[1] Hairer, Lubich, Wanner, "Geometric Numerical Integration: Structure-Preserving Algorithms for Ordinary Differential Equations", 2nd ed., section IV.4, pg 109ff, Springer, 2006.
The discrete variables d are updated by the time stepper upon occurrence of specific events, which terminate a continuous interval. The Integrator detects these using a set of scalar-valued event trigger functions shown as equation (3) above. An event trigger function for a particular event must be designed so that it has a zero crossing when the event occurs. The integrator can thus watch for sign changes in event triggers and terminate the current step when a zero crossing occurs, notifying the system and giving it a chance to handle the event; that is, update its state variables discontinuously.
The zero crossings of continuous event trigger functions will be isolated quickly; discontinuous ones have to be "binary chopped" which is more expensive but they will still work.
We are given a set of weights W for the y's, and a set of tolerances T for the constraint errors. Given an accuracy specification (like 0.1%), the integrators here are expected to solve for y(t) such that the local error |W*yerr|_RMS <= accuracy, and |T*c(t,y)|_RMS <= accuracy at all times.
TODO: isolation tolerances for witnesses; dealing with simultaneity.
When a step is successful, it will return an indication of what caused it to stop where it did.
When unsuccessful it will throw an exception so you won't see any return value.
When return of control is due ONLY to reaching a report time, (status is ReachedReportTime) the integrator's getState() method may return an interpolated value at an earlier time than its getAdvancedState() method would return. For the other returns, and whenever the report time coincides with the end of an internal step, getState() and getAdvancedState() will be identical.
Note: we ensure algorithmically that no report time, scheduled time, or final time t can occur within an event window, that is, we will never have t_low < t < t_high for any interesting t. Further, t_report, t_scheduled and t_final can coincide with t_high but only t_report can be at t_low. The interior of t_low:t_high is a "no man's land" where we don't understand the solution, so must be avoided.
Enumerator | |
---|---|
ReachedReportTime | stopped only to report; might be interpolated |
ReachedEventTrigger | localized an event; this is the before state (interpolated) |
ReachedScheduledEvent | reached the limit provided in stepTo() (scheduled event) |
TimeHasAdvanced | user requested control whenever an internal step is successful |
ReachedStepLimit | took a lot of internal steps but didn't return control yet |
EndOfSimulation | termination; don't call again |
StartOfContinuousInterval | the beginning of a continuous interval: either the start of the simulation, or t_high after an event handler has modified the state. |
InvalidSuccessfulStepStatus |
Once the simulation has ended, getTerminationReason() may be called to find out what caused it to end.
Enumerator | |
---|---|
ReachedFinalTime | The simulation reached the time specified by setFinalTime(). |
AnUnrecoverableErrorOccurred | An error occurred which the Integrator was unable to handle. |
EventHandlerRequestedTermination | An event handler function requested that the simulation terminate immediately. |
InvalidTerminationReason | This will be returned if getTerminationReason() is called before the simulation has ended. |
|
inline |
SimTK::Integrator::~Integrator | ( | ) |
const char* SimTK::Integrator::getMethodName | ( | ) | const |
Get the name of this integration method.
int SimTK::Integrator::getMethodMinOrder | ( | ) | const |
Get the minimum order this Integrator may use.
int SimTK::Integrator::getMethodMaxOrder | ( | ) | const |
Get the maximum order this Integrator may use.
bool SimTK::Integrator::methodHasErrorControl | ( | ) | const |
Get whether this Integrator provides error control.
An error controlled Integrator will dynamically adjust its step size to maintain the level of accuracy specified with setAccuracy(). An Integrator which does not provide error control cannot do this, and will usually ignore the value specified with setAccuracy().
void SimTK::Integrator::initialize | ( | const State & | state | ) |
Supply the integrator with a starting state.
This must be called before the first call to stepBy() or stepTo(). The specified state is copied into the Integrator's internally maintained current state; subsequent changes to the State object passed in here will not affect the integration.
void SimTK::Integrator::reinitialize | ( | Stage | stage, |
bool | shouldTerminate | ||
) |
After an event handler has made a discontinuous change to the Integrator's "advanced state", this method must be called to reinitialize the Integrator.
Event handlers can do varying amounts of damage and some events will require no reinitialization, or minimal reinitialization, depending on details of the particular integration method. So after the handler has mangled our State, we tell the Integrator the lowest Stage which was changed and allow the Integrator to figure out how much reinitialization to do.
If "shouldTerminate" is passed in true, the Integrator will wrap things up and report that the end of the simulation has been reached.
const State& SimTK::Integrator::getState | ( | ) | const |
Return a State corresponding to the "current" time at the end of the last call to stepTo() or stepBy().
This may be an interpolated value earlier than getAdvancedState().
|
inline |
Get the time of the current State. This is equivalent to calling getState().getTime().
bool SimTK::Integrator::isStateInterpolated | ( | ) | const |
Get whether getState() will return an interpolated state or just the same thing as getAdvancedState() does.
In most cases, you should not have reason to care whether the state is interpolated or not.
const State& SimTK::Integrator::getAdvancedState | ( | ) | const |
Return the state representing the trajectory point to which the integrator has irreversibly advanced.
This may be later than the state return by getState().
|
inline |
Get the time of the advanced State. This is equivalent to calling getAdvancedState().getTime().
State& SimTK::Integrator::updAdvancedState | ( | ) |
Get a non-const reference to the advanced state.
Real SimTK::Integrator::getAccuracyInUse | ( | ) | const |
Get the accuracy which is being used for error control.
Usually this is the same value that was specified to setAccuracy().
Real SimTK::Integrator::getConstraintToleranceInUse | ( | ) | const |
Get the constraint tolerance which is being used for error control.
Usually this is the same value that was specified to setConstraintTolerance().
|
static |
Get a human readable description of the reason a step returned.
SuccessfulStepStatus SimTK::Integrator::stepTo | ( | Real | reportTime, |
Real | scheduledEventTime = Infinity |
||
) |
Integrate the System until something happens which requires outside processing, and return a status code describing what happened.
reportTime | the time of the next scheduled report |
scheduledEventTime | the time of the next scheduled event |
SuccessfulStepStatus SimTK::Integrator::stepBy | ( | Real | interval, |
Real | scheduledEventTime = Infinity |
||
) |
Vec2 SimTK::Integrator::getEventWindow | ( | ) | const |
const Array_<Event::Trigger>& SimTK::Integrator::getEventTransitionsSeen | ( | ) | const |
bool SimTK::Integrator::isSimulationOver | ( | ) | const |
TerminationReason SimTK::Integrator::getTerminationReason | ( | ) | const |
Get the reason the simulation terminated.
This should only be called if isSimulationOver() returns true.
|
static |
Get a human readable description of the termination reason.
void SimTK::Integrator::resetAllStatistics | ( | ) |
Reset all statistics to zero.
Real SimTK::Integrator::getActualInitialStepSizeTaken | ( | ) | const |
Get the size of the first successful step after the last initialize() call.
Real SimTK::Integrator::getPreviousStepSizeTaken | ( | ) | const |
Get the size of the most recent successful step.
Real SimTK::Integrator::getPredictedNextStepSize | ( | ) | const |
int SimTK::Integrator::getNumStepsAttempted | ( | ) | const |
Get the total number of steps that have been attempted (successfully or unsuccessfully) since the last call to resetAllStatistics().
int SimTK::Integrator::getNumStepsTaken | ( | ) | const |
Get the total number of steps that have been successfully taken since the last call to resetAllStatistics().
int SimTK::Integrator::getNumRealizations | ( | ) | const |
Get the total number of state realizations that have been performed since the last call to resetAllStatistics().
int SimTK::Integrator::getNumQProjections | ( | ) | const |
Get the total number of times a state positions Q have been projected since the last call to resetAllStatistics().
int SimTK::Integrator::getNumUProjections | ( | ) | const |
Get the total number of times a state velocities U have been projected since the last call to resetAllStatistics().
int SimTK::Integrator::getNumProjections | ( | ) | const |
Get the total number of times a state has been projected (counting both Q and U projections) since the last call to resetAllStatistics().
int SimTK::Integrator::getNumErrorTestFailures | ( | ) | const |
Get the number of attempted steps that have failed due to the error being unacceptably high since the last call to resetAllStatistics().
int SimTK::Integrator::getNumConvergenceTestFailures | ( | ) | const |
Get the number of attempted steps that failed due to non-convergence of internal step iterations.
This is most common with iterative methods but can occur if for some reason a step can't be completed. It is reset to zero by resetAllStatistics.
int SimTK::Integrator::getNumRealizationFailures | ( | ) | const |
Get the number of attempted steps that have failed due to an error when realizing the state since the last call to resetAllStatistics().
int SimTK::Integrator::getNumQProjectionFailures | ( | ) | const |
Get the number of attempted steps that have failed due to an error when projecting the state positions (Q) since the last call to resetAllStatistics().
int SimTK::Integrator::getNumUProjectionFailures | ( | ) | const |
Get the number of attempted steps that have failed due to an error when projecting the state velocities (U) since the last call to resetAllStatistics().
int SimTK::Integrator::getNumProjectionFailures | ( | ) | const |
Get the number of attempted steps that have failed due to an error when projecting the state (either a Q- or U-projection) since the last call to resetAllStatistics().
int SimTK::Integrator::getNumConvergentIterations | ( | ) | const |
For iterative methods, get the number of internal step iterations in steps that led to convergence (not necessarily successful steps).
Reset to zero by resetAllStatistics().
int SimTK::Integrator::getNumDivergentIterations | ( | ) | const |
For iterative methods, get the number of internal step iterations in steps that did not lead to convergence.
Reset to zero by resetAllStatistics().
int SimTK::Integrator::getNumIterations | ( | ) | const |
For iterative methods, this is the total number of internal step iterations taken regardless of whether those iterations led to convergence or to successful steps.
This is the sum of the number of convergent and divergent iterations which are available separately.
void SimTK::Integrator::setFinalTime | ( | Real | tFinal | ) |
Set the time at which the simulation should end.
The default is infinity. Some integrators may not support this option.
void SimTK::Integrator::setInitialStepSize | ( | Real | hinit | ) |
Set the initial step size that should be attempted.
The default depends on the integration method. Some integrators may not support this option.
void SimTK::Integrator::setMinimumStepSize | ( | Real | hmin | ) |
Set the minimum step size that should ever be used.
The default depends on the integration method. Some integrators may not support this option.
void SimTK::Integrator::setMaximumStepSize | ( | Real | hmax | ) |
Set the maximum step size that should ever be used.
The default depends on the integration method. Some integrators may not support this option.
void SimTK::Integrator::setFixedStepSize | ( | Real | stepSize | ) |
Set the integrator to use a single fixed step size for all steps.
This is exactly equivalent to calling setInitialStepSize(), setMinimumStepSize(), and setMaximumStepSize(), passing the same value to each one. This will therefore not work correctly if the integrator does not support minimum and/or maximum step sizes.
void SimTK::Integrator::setAccuracy | ( | Real | accuracy | ) |
Set the overall accuracy that should be used for integration.
If the Integrator does not support error control (methodHasErrorControl() returns false), this may have no effect.
void SimTK::Integrator::setConstraintTolerance | ( | Real | consTol | ) |
Set the tolerance within which constraints must be satisfied.
void SimTK::Integrator::setUseInfinityNorm | ( | bool | useInfinityNorm | ) |
(Advanced) Use infinity norm (maximum absolute value) instead of default RMS norm to evaluate whether accuracy has been achieved for states and for constraint tolerance.
The infinity norm is more strict but may permit use of a looser accuracy request.
bool SimTK::Integrator::isInfinityNormInUse | ( | ) | const |
(Advanced) Are we currently using the infinity norm?
void SimTK::Integrator::setInternalStepLimit | ( | int | nSteps | ) |
void SimTK::Integrator::setReturnEveryInternalStep | ( | bool | shouldReturn | ) |
Set whether the Integrator should return from stepTo() or stepBy() after every internal step, even if no event has occurred and the report time has not been reached.
The default is false.
void SimTK::Integrator::setProjectEveryStep | ( | bool | forceProject | ) |
Set whether the system should be projected back to the constraint manifold after every step.
If this is false, projection will only be performed when the constraint error exceeds the allowed tolerance.
void SimTK::Integrator::setAllowInterpolation | ( | bool | shouldInterpolate | ) |
Set whether the Integrator is permitted to return interpolated states for reporting purposes which may be less accurate than the "real" states that form the trajectory.
Setting this to false may significantly affect performance, since the Integrator will be forced to decrease its step size at every scheduled reporting time.
This option is generally only meaningful if interpolated states are less accurate than other states on the trajectory. If an Integrator can produce interpolated states that have the same accuracy as the rest of the trajectory, it may ignore this option.
void SimTK::Integrator::setProjectInterpolatedStates | ( | bool | shouldProject | ) |
Set whether interpolated states should be projected back to the constraint manifold after interpolation is performed.
The default is "true".
void SimTK::Integrator::setForceFullNewton | ( | bool | forceFullNewton | ) |
(Advanced) Constraint projection may use an out-of-date iteration matrix for efficiency.
You can force strict use of a current iteration matrix recomputed at each iteration if you want.
|
inlinestatic |
OBSOLETE: use getSuccessfulStepStatusString().
|
inlineprotected |
|
inlineprotected |
|
friend |
|
protected |