Simbody

SubsystemGuts.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
00002 #define SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-10 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00035 #include "SimTKcommon/basics.h"
00036 #include "SimTKcommon/Simmatrix.h"
00037 #include "SimTKcommon/internal/State.h"
00038 
00039 #include <cassert>
00040 
00041 namespace SimTK {
00042 
00043 class System;
00044 class DecorativeGeometry;
00045 
00046 
00050 class SimTK_SimTKCOMMON_EXPORT Subsystem::Guts {
00051 public:
00052     Guts(const Guts&);
00053     Guts& operator=(const Guts&);
00054 
00055     // This constructor is for use by concrete Subsystems. Note that this
00056     // serves as a default constructor since both arguments have defaults.
00057     explicit Guts(const String& name="<NONAME>", 
00058                   const String& version="0.0.0");
00059     virtual ~Guts();
00060 
00061     const String& getName()    const;
00062     const String& getVersion() const;
00063 
00064     // Use these to allocate state variables and cache entries that are owned
00065     // by this Subsystem.
00066 
00067     // qdot, qdotdot also allocated in cache
00068     QIndex allocateQ(State& s, const Vector& qInit) const;
00069     // udot is also allocated in the cache
00070     UIndex allocateU(State& s, const Vector& uInit) const;
00071     // zdot is also allocated in the cache
00072     ZIndex allocateZ(State& s, const Vector& zInit) const;
00073 
00074     DiscreteVariableIndex allocateDiscreteVariable(State& s, Stage g, AbstractValue* v) const;
00075     DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
00076        (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const; 
00077 
00078     // Cache entries
00079     CacheEntryIndex allocateCacheEntry
00080        (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
00081     CacheEntryIndex allocateCacheEntry
00082        (const State& state, Stage g, AbstractValue* v) const 
00083     {   return allocateCacheEntry(state, g, g, v); }
00084     CacheEntryIndex allocateLazyCacheEntry   
00085        (const State& state, Stage earliest, AbstractValue* v) const 
00086     {   return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
00087 
00088     // qerr, uerr, udoterr are all cache entries, not variables
00089     // allocating udoterr also allocates matching multipliers
00090     QErrIndex allocateQErr(const State& s, int nqerr) const;
00091     UErrIndex allocateUErr(const State& s, int nuerr) const;
00092     UDotErrIndex allocateUDotErr(const State& s, int nudoterr) const;
00093     EventTriggerByStageIndex allocateEventTriggersByStage(const State&, Stage, int ntriggers) const;
00094 
00095 
00096     // These return views on State shared global resources. The views
00097     // are private to this subsystem, but the global resources themselves
00098     // are not allocated until the *System* advances to stage Model.
00099     // Note that there is no subsystem equivalent of the State's "y"
00100     // vector because in general a subsystem's state variables will
00101     // not be contiguous. However, a subsystem's q's, u's, and z's
00102     // will all be contiguous within those arrays.
00103     const Vector& getQ(const State&) const;
00104     const Vector& getU(const State&) const;
00105     const Vector& getZ(const State&) const;
00106     const Vector& getQDot(const State&) const;
00107     const Vector& getUDot(const State&) const;
00108     const Vector& getZDot(const State&) const;
00109     const Vector& getQDotDot(const State&) const;
00110     const Vector& getQErr(const State&) const;
00111     const Vector& getUErr(const State&) const;
00112     const Vector& getUDotErr(const State&) const;
00113     const Vector& getMultipliers(const State&) const;
00114     const Vector& getEventTriggersByStage(const State&, Stage) const;
00115 
00116     // These return writable access to this subsystem's partition in the
00117     // State pool of continuous variables. These can be called at Stage::Model
00118     // or higher, and if necesary they invalidate the Position (q), Velocity (u),
00119     // or Dynamics (z) stage respectively.
00120     Vector& updQ(State&) const; // invalidates Stage::Position
00121     Vector& updU(State&) const; // invalidates Stage::Velocity
00122     Vector& updZ(State&) const; // invalidates Stage::Dynamics
00123 
00124     // For convenience.
00125     void setQ(State& s, const Vector& q) const {
00126         assert(q.size() == getNQ(s));
00127         updQ(s) = q;
00128     }
00129     void setU(State& s, const Vector& u) const {
00130         assert(u.size() == getNU(s));
00131         updU(s) = u;
00132     }
00133     void setZ(State& s, const Vector& z) const {
00134         assert(z.size() == getNZ(s));
00135         updZ(s) = z;
00136     }
00137 
00138     // These update the State cache which is mutable; hence, const State. They
00139     // can be called only if the previous stage has already been realized, e.g.,
00140     // updQDot() is allowed only while realizing the Velocity stage, requiring
00141     // that Position stage has already been realized.
00142     Vector& updQDot(const State&) const;
00143     Vector& updUDot(const State&) const;
00144     Vector& updZDot(const State&) const;
00145     Vector& updQDotDot(const State&) const;
00146     Vector& updQErr(const State&) const;
00147     Vector& updUErr(const State&) const;
00148     Vector& updUDotErr(const State&) const;
00149     Vector& updMultipliers(const State&) const;
00150     Vector& updEventTriggersByStage(const State&, Stage) const;
00151 
00152     // These pull out the State entries which belong exclusively to
00153     // this Subsystem. These variables and cache entries are available
00154     // as soon as this subsystem is at stage Model.
00155     Stage getStage(const State&) const;
00156     const AbstractValue& getDiscreteVariable(const State&, DiscreteVariableIndex) const;
00157 
00158     Real getDiscreteVarLastUpdateTime(const State& s, DiscreteVariableIndex dx) const
00159     {   return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
00160     CacheEntryIndex getDiscreteVarUpdateIndex(const State& s, DiscreteVariableIndex dx) const
00161     {   return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
00162     const AbstractValue& getDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00163     {   return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00164     AbstractValue& updDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00165     {   return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00166     bool isDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
00167     {   return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00168     void markDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
00169     {   return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00170 
00171     // State is *not* mutable here -- must have write access to change state variables.
00172     AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
00173     const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
00174     // State is mutable here.
00175     AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
00176 
00177     bool isCacheValueRealized(const State&, CacheEntryIndex) const;
00178     void markCacheValueRealized(const State&, CacheEntryIndex) const;
00179     void markCacheValueNotRealized(const State&, CacheEntryIndex) const;
00180 
00181     // Dimensions. These are valid at System Stage::Model while access to the various
00182     // arrays may have stricter requirements. Hence it is better to use these
00183     // routines than to get a reference to a Vector above and ask for its size().
00184 
00185     SystemQIndex getQStart      (const State&) const;
00186     int getNQ          (const State&) const;
00187     SystemUIndex getUStart      (const State&) const;
00188     int getNU          (const State&) const;
00189     SystemZIndex getZStart      (const State&) const;
00190     int getNZ          (const State&) const;
00191     SystemQErrIndex getQErrStart   (const State&) const;
00192     int getNQErr       (const State&) const;
00193     SystemUErrIndex getUErrStart   (const State&) const;
00194     int getNUErr       (const State&) const;
00195     SystemUDotErrIndex getUDotErrStart(const State&) const;
00196     int getNUDotErr    (const State&) const;
00197     SystemMultiplierIndex getMultipliersStart(const State&) const;
00198     int getNMultipliers(const State&) const;
00199     SystemEventTriggerByStageIndex   getEventTriggerStartByStage(const State&, Stage) const;
00200     int getNEventTriggersByStage(const State&, Stage) const;
00201 
00202     MeasureIndex adoptMeasure(AbstractMeasure& m);
00203     AbstractMeasure getMeasure(MeasureIndex) const;
00204     template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
00205     {   return Measure_<T>::getAs(getMeasure(mx));}
00206 
00207     bool isInSystem() const;
00208     bool isInSameSystem(const Subsystem& otherSubsystem) const;
00209 
00210     const System& getSystem() const;
00211     System&       updSystem();
00212 
00213     SubsystemIndex getMySubsystemIndex() const;
00214 
00215     // Internal use only
00216     const Subsystem& getOwnerSubsystemHandle() const;
00217     Subsystem& updOwnerSubsystemHandle();
00218     void setOwnerSubsystemHandle(Subsystem&);
00219     bool hasOwnerSubsystemHandle() const;
00220 
00221     void setSystem(System&, SubsystemIndex);
00222 
00223     class GutsRep;
00224     explicit Guts(GutsRep* r) : rep(r) { }
00225     bool                hasRep() const {return rep!=0;}
00226     const GutsRep& getRep() const {assert(rep); return *rep;}
00227     GutsRep&       updRep() const {assert(rep); return *rep;}
00228     void setRep(GutsRep& r) {assert(!rep); rep = &r;}
00229 
00230     bool subsystemTopologyHasBeenRealized() const;
00231     void invalidateSubsystemTopologyCache() const;
00232 
00233     // These are wrappers for the virtual methods defined below. They
00234     // are used to ensure good behavior.
00235 
00236     Subsystem::Guts* clone() const;
00237 
00238     // Realize this subsystem's part of the State from Stage-1 to Stage
00239     // for the indicated stage. After doing some checking, these routines
00240     // call the concrete subsystem's corresponding virtual method, and
00241     // on return they make sure the stage has been properly updated.
00242     // Note that these will do nothing if the Subsystem stage is already
00243     // at or greater than the indicated stage.
00244     void realizeSubsystemTopology    (State&) const;
00245     void realizeSubsystemModel       (State&) const;
00246     void realizeSubsystemInstance    (const State&) const;
00247     void realizeSubsystemTime        (const State&) const;
00248     void realizeSubsystemPosition    (const State&) const;
00249     void realizeSubsystemVelocity    (const State&) const;
00250     void realizeSubsystemDynamics    (const State&) const;
00251     void realizeSubsystemAcceleration(const State&) const;
00252     void realizeSubsystemReport      (const State&) const;
00253 
00254     // Calculate weights and tolerances.
00255 
00256     // Given the current values of our own position variables,
00257     // calculate a "unit weighting" for changes to these position
00258     // variables. 
00259     // @param[out] weights must be resizable or already the right size
00260     // @pre State must be realized to >= Stage::Position (this subsystem).
00261     void calcQUnitWeights(const State&, Vector& weights) const;
00262 
00263     // Given the current values of our own position variables,
00264     // calculate a "unit weighting" for changes to our velocity
00265     // variables.
00266     // @param[out] weights must be resizable or already the right size
00267     // @pre State must be realized to >= Stage::Position (this subsystem).
00268     void calcUUnitWeights(const State&, Vector& weights) const;
00269 
00270     // Given the current values of our own position variables,
00271     // calculate a "unit weighting" for changes to our auxiliary
00272     // variables.
00273     // @param[out] weights must be resizable or already the right size
00274     // @pre State must be realized to >= Stage::Position (this subsystem).
00275     void calcZUnitWeights(const State&, Vector& weights) const;
00276 
00277     // Calculate a "unit tolerance" for errors in each of this subsystem's
00278     // position-level constraints.
00279     // @param[out] tolerances must be resizable or already the right size
00280     // @pre State must be realized to >= Stage::Model (this subsystem).
00281     // @remark Tolerances are expected to be constant during a study; typically
00282     //         they just reflect the units in which the contraint equations
00283     //         are calculated, e.g. angles or lengths.
00284     void calcQErrUnitTolerances(const State&, Vector& tolerances) const;
00285 
00286     // Calculate a "unit tolerance" for errors in each of this subsystem's
00287     // velocity-level constraints.
00288     // @param[out] tolerances must be resizable or already the right size
00289     // @pre State must be realized to >= Stage::Model (this subsystem).
00290     // @remark Tolerances are expected to be constant during a study; typically
00291     //         they just reflect the units in which the contraint equations
00292     //         are calculated, e.g. angles/time or lengths/time.
00293     void calcUErrUnitTolerances(const State&, Vector& tolerances) const;
00294 
00295     // Generate decorative geometry computable at a specific stage. This will
00296     // throw an exception if this subsystem's state hasn't already been realized
00297     // to that stage. Note that the list is not inclusive -- you have to
00298     // request geometry from each stage to get all of it.
00299     // The generated geometry will be *appended* to the supplied output vector.
00300     void calcDecorativeGeometryAndAppend
00301        (const State&, Stage, Array_<DecorativeGeometry>&) const;
00302     
00303     void createScheduledEvent(const State& state, EventId& eventId) const;
00304     void createTriggeredEvent(const State& state, EventId& eventId, 
00305                               EventTriggerByStageIndex& triggerFunctionIndex,
00306                               Stage stage) const;
00307 
00308     // These methods are called by the corresponding methods of System.
00309     // Each subsystem is responsible for defining its own events, and
00310     // System then combines the information from them, and dispatches events
00311     // to the appropriate subsystems for handling when they occur.
00312     virtual void calcEventTriggerInfo
00313        (const State&, Array_<EventTriggerInfo>&) const;
00314     virtual void calcTimeOfNextScheduledEvent
00315        (const State&, Real& tNextEvent, Array_<EventId>& eventIds, 
00316         bool includeCurrentTime) const;
00317     virtual void calcTimeOfNextScheduledReport
00318        (const State&, Real& tNextEvent, Array_<EventId>& eventIds, 
00319         bool includeCurrentTime) const;
00320     virtual void handleEvents
00321        (State&, Event::Cause, const Array_<EventId>& eventIds,
00322         Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols,
00323         Stage& lowestModified, bool& shouldTerminate) const;
00324     virtual void reportEvents
00325        (const State&, Event::Cause, const Array_<EventId>& eventIds) const;
00326 
00327 protected:
00328     // These virtual methods should be overridden in concrete Subsystems as
00329     // necessary. They should never be called directly; instead call the
00330     // wrapper routines above, which have the same name but without the "Impl"
00331     // (implementation) at the end.
00332     
00333     // The "realize..." wrappers will call the "realize...Impl" methods below
00334     // only when the current stage for the Subsystem is the one just prior
00335     // to the stage being realized. For example, realizeSubsystemVelocityImpl()
00336     // is called by realizeSubsystemVelocity() only when the passed-in State
00337     // shows this subsystem's stage to be exactly Stage::Position.
00338     //
00339     // The default implementations provided here do nothing. That means the
00340     // wrappers will simply check that the current stage is correct and
00341     // advance it if necessary.
00342 
00343     // The destructor is already virtual; see above.
00344 
00345     virtual Subsystem::Guts* cloneImpl() const = 0;
00346 
00347     virtual int realizeSubsystemTopologyImpl(State& s) const;
00348     virtual int realizeSubsystemModelImpl(State& s) const;
00349     virtual int realizeSubsystemInstanceImpl(const State& s) const;
00350     virtual int realizeSubsystemTimeImpl(const State& s) const;
00351     virtual int realizeSubsystemPositionImpl(const State& s) const;
00352     virtual int realizeSubsystemVelocityImpl(const State& s) const;
00353     virtual int realizeSubsystemDynamicsImpl(const State& s) const;
00354     virtual int realizeSubsystemAccelerationImpl(const State& s) const;
00355     virtual int realizeSubsystemReportImpl(const State& s) const;
00356 
00357     virtual int calcQUnitWeightsImpl(const State& s, Vector& weights) const;
00358     virtual int calcUUnitWeightsImpl(const State& s, Vector& weights) const;
00359     virtual int calcZUnitWeightsImpl(const State& s, Vector& weights) const;
00360     virtual int calcQErrUnitTolerancesImpl(const State& s, Vector& tolerances) const;
00361     virtual int calcUErrUnitTolerancesImpl(const State& s, Vector& tolerances) const;
00362     virtual int calcDecorativeGeometryAndAppendImpl
00363        (const State&, Stage, Array_<DecorativeGeometry>&) const;
00364 
00365     void advanceToStage(const State& s, Stage g) const;
00366 
00367 private:
00368     // this is the only data member in the base class
00369     GutsRep* rep; // opaque implementation of Subsystem::Guts base class.
00370 
00371 friend class GutsRep;
00372 };
00373 
00374 } // namespace SimTK
00375 
00376 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines