1 #ifndef SimTK_SIMMATH_GEODESIC_INTEGRATOR_H_     2 #define SimTK_SIMMATH_GEODESIC_INTEGRATOR_H_   136     enum { 
NQ = Eqn::NQ, 
NC = Eqn::NC, 
N = 2*
NQ };
   142     :   m_eqn(eqn), m_accuracy(accuracy), m_consTol(constraintTol),
   143         m_hInit(
NaN), m_hLast(
NaN), m_hNext(
Real(0.1)), m_nInitialize(0) 
   144     {   reinitializeCounters(); }
   152         reinitializeCounters();
   153         m_hInit = m_hLast = 
NaN;
   156         if (!m_eqn.projectIfNeeded(m_consTol, m_t, m_y)) {
   158             m_eqn.calcConstraintErrors(m_t, m_y, cerr);
   161                 "GeodesicIntegrator::initialize()",
   162                 "Couldn't project constraints to tol=%g;"   163                 " largest error was %g.", m_consTol, consErr);
   165         m_eqn.calcDerivs(m_t, m_y, m_ydot);
   173         m_eqn.calcDerivs(m_t, m_y, m_ydot);
   175         m_eqn.calcConstraintErrors(m_t, m_y, cerr);
   177         if (consErr > m_consTol)
   179                 "GeodesicIntegrator::setTimeAndState()",
   180                 "Supplied state failed to satisfy constraints to tol=%g;"   181                 " largest error was %g.", m_consTol, consErr);
   246         for (
int i=0; i < Z; ++i) {
   248             if (aval > norm) norm = aval;
   257         for (
int i=0; i< Z; ++i) 
   259         return std::sqrt(norm/Z);
   280     void reinitializeCounters() {
   281         m_nStepsTaken=m_nStepsAttempted=0;
   282         m_nErrtestFailures=m_nProjectionFailures=0;
   285     int m_nStepsAttempted;
   286     int m_nErrtestFailures;
   287     int m_nProjectionFailures;
   290 template <
class Eqn> 
void   293     const Real HysteresisLow =  
Real(0.9), HysteresisHigh = 
Real(1.2);
   296     const Real hStretch = MaxStretch*m_hNext;
   300     Real t1 = m_t + m_hNext; 
   303     if (t1 + hStretch > tStop) 
   314         h = t1 - m_t; assert(h>0);
   315         takeRKMStep(h, y1, y1err);
   317         if (errNorm > m_accuracy) {
   318             ++m_nErrtestFailures;
   321                 "GeodesicIntegrator::takeOneStep()", 
   322                 "Accuracy %g worse than required %g at t=%g with step size"   323                 " h=%g; can't go any smaller.", errNorm, m_accuracy, m_t, h);
   326             Real hNew = Safety * h * std::sqrt(std::sqrt(m_accuracy/errNorm));
   327             hNew = 
clamp(MinShrink*h, hNew, HysteresisLow*h);
   332         if (m_eqn.projectIfNeeded(m_consTol, t1, y1))
   337         ++m_nProjectionFailures;
   340             "GeodesicIntegrator::takeOneStep()", 
   341             "Projection failed to reach constraint tolerance %g at t=%g "   342             "with step size h=%g; can't shrink step further.", 
   345         const Real hNew = MinShrink*h;
   353     if (m_nStepsTaken==1) m_hInit = h; 
   354     m_t = t1; m_y = y1; m_hLast = h;
   355     m_eqn.calcDerivs(m_t, m_y, m_ydot);
   362         Real hNew = errNorm == 0 ? MaxGrow*h
   363             :  Safety * h * std::sqrt(std::sqrt(m_accuracy/errNorm));
   364         if (hNew < HysteresisHigh*h) hNew = h; 
   370 template <
class Eqn> 
void   372     const Real h2=h/2, h3=h/3, h6=h/6, h8=h/8;
   373     const Real t0=m_t, t1=m_t+h;
   375     const Vec<N>& f0 = m_ydot;
   376     Vec<N> f1, f2, f3, f4, ysave;
   377     m_eqn.calcDerivs(t0+h3, y0 + h3* f0,         f1);
   378     m_eqn.calcDerivs(t0+h3, y0 + h6*(f0 + f1),   f2);
   379     m_eqn.calcDerivs(t0+h2, y0 + h8*(f0 + 3*f2), f3);
   382     ysave = y0 + h2*(f0 - 3*f2 + 4*f3);
   383     m_eqn.calcDerivs(t1, ysave, f4);
   389     y1 = y0 + h6*(f0 + 4*f3 + f4);
   396     for (
int i=0; i<
N; ++i)
   397         y1err[i] = 
std::abs(y1[i]-ysave[i]) / 5;
   402 #endif // SimTK_SIMMATH_GEODESIC_INTEGRATOR_H_ const Vec< N > & getY() const 
Return the complete current state as a Vec<N>. 
Definition: GeodesicIntegrator.h:230
 
void initialize(Real t, const Vec< N > &y)
Call this once before taking a series of steps. 
Definition: GeodesicIntegrator.h:150
 
void takeOneStep(Real tStop)
Advance time and state by one error-controlled step and return, but in no case advance past t=tStop...
Definition: GeodesicIntegrator.h:291
 
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
 
Real getActualInitialStepSizeTaken() const 
Return the size of the first accepted step to be taken after the most recent initialize() call...
Definition: GeodesicIntegrator.h:198
 
GeodesicIntegrator(const Eqn &eqn, Real accuracy, Real constraintTol)
Construct an integrator for the given set of equations eqn, which are to be solved to the given accur...
Definition: GeodesicIntegrator.h:141
 
const Vec< NQ > & getU() const 
Return just the "velocity" variables u from the current state. 
Definition: GeodesicIntegrator.h:234
 
ELEM min(const VectorBase< ELEM > &v)
Definition: VectorMath.h:178
 
#define SimTK_ERRCHK2_ALWAYS(cond, whereChecked, fmt, a1, a2)          
Definition: ExceptionMacros.h:289
 
#define SimTK_ERRCHK4_ALWAYS(cond, whereChecked, fmt, a1, a2, a3, a4)
Definition: ExceptionMacros.h:297
 
void setTimeAndState(Real t, const Vec< N > &y)
Set initial time and state prior to integrating. 
Definition: GeodesicIntegrator.h:171
 
SimTK_Real Real
This is the default compiled-in floating point type for SimTK, either float or double. 
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:593
 
const Real NaN
This is the IEEE "not a number" constant for this implementation of the default-precision Real type; ...
 
unsigned char square(unsigned char u)
Definition: Scalar.h:351
 
const Vec< N > & getYDot() const 
Return the complete set of time derivatives of the current state. 
Definition: GeodesicIntegrator.h:236
 
const Real & getTime() const 
Return the current time. 
Definition: GeodesicIntegrator.h:228
 
int getNumErrorTestFailures() const 
How many steps were rejected because they did not satisfy the accuracy requirement, since the most recent initalize() call. 
Definition: GeodesicIntegrator.h:211
 
void setNextStepSizeToTry(Real h)
Use this if you think you know a better initial step size to try than the default. 
Definition: GeodesicIntegrator.h:186
 
Includes internal headers providing declarations for the basic SimTK Core classes, including Simmatrix. 
 
Definition: GeodesicIntegrator.h:136
 
int getNumStepsAttempted() const 
Return the total number of steps that were attempted since the most recent initialize() call...
Definition: GeodesicIntegrator.h:206
 
int getNumProjectionFailures() const 
How many steps were rejected because the projectIfNeeded() method was unable to satisfy the constrain...
Definition: GeodesicIntegrator.h:215
 
float norm(const conjugate< float > &c)
Definition: conjugate.h:775
 
#define SimTK_ERRCHK3_ALWAYS(cond, whereChecked, fmt, a1, a2, a3)    
Definition: ExceptionMacros.h:293
 
Definition: GeodesicIntegrator.h:136
 
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
 
This is the header file that every Simmath compilation unit should include first. ...
 
double clamp(double low, double v, double high)
If v is in range low <= v <= high then return v, otherwise return the nearest bound; this function do...
Definition: Scalar.h:660
 
const Real SignificantReal
SignificantReal is the smallest value that we consider to be clearly distinct from roundoff error whe...
 
int getNumStepsTaken() const 
Return the number of successful time steps taken since the most recent initialize() call...
Definition: GeodesicIntegrator.h:202
 
static Real calcNormInf(const Vec< Z > &v)
This is a utility routine that returns the infinity norm (maximum absolute value) contained in a fixe...
Definition: GeodesicIntegrator.h:244
 
static Real calcNormRMS(const Vec< Z > &v)
This is a utility routine that returns the RMS norm of a fixed-size, scalar Vec. 
Definition: GeodesicIntegrator.h:255
 
const Vec< NQ > & getQ() const 
Return just the "position" variables q from the current state. 
Definition: GeodesicIntegrator.h:232
 
Real getNextStepSizeToTry() const 
Return the size of the next time step the integrator will attempt on the next call to takeOneStep()...
Definition: GeodesicIntegrator.h:189
 
int getNumInitializations() const 
Return the number of calls to initialize() since construction of this integrator object. 
Definition: GeodesicIntegrator.h:219
 
Real getRequiredAccuracy() const 
Return the accuracy requirement as set in the constructor. 
Definition: GeodesicIntegrator.h:192
 
This is a stripped-down numerical integrator for small ODE or DAE problems whose size is known at com...
Definition: GeodesicIntegrator.h:134
 
Definition: GeodesicIntegrator.h:136
 
Real getConstraintTolerance() const 
Return the constraint tolerance as set in the constructor. 
Definition: GeodesicIntegrator.h:194
 
static const Vec & getAs(const ELT *p)
Recast an ordinary C++ array E[] to a const Vec<M,E,S>; assumes compatible length, stride, and packing. 
Definition: Vec.h:902
 
const Vec< NQ > & getUDot() const 
Return just the derivatives udot of the "velocity" variables u. 
Definition: GeodesicIntegrator.h:240
 
const Vec< NQ > & getQDot() const 
Return just the derivatives qdot of the "position" variables q. 
Definition: GeodesicIntegrator.h:238