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-7 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 #include "SimTKcommon/internal/System.h"
00039 
00040 #include <cassert>
00041 
00042 namespace SimTK {
00043 
00044 class System;
00045 class DecorativeGeometry;
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     DiscreteVariableIndex allocateDiscreteVariable(State& s, Stage g, AbstractValue* v) const;
00074 
00075     // Cache entries
00076     CacheEntryIndex allocateCacheEntry   (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
00077     CacheEntryIndex allocateCacheEntry   (const State& state, Stage g, AbstractValue* v) const 
00078     {   return allocateCacheEntry(state, g, g, v); }
00079     // qerr, uerr, udoterr are all cache entries, not variables
00080     // allocating udoterr also allocates matching multipliers
00081     QErrIndex allocateQErr(const State& s, int nqerr) const;
00082     UErrIndex allocateUErr(const State& s, int nuerr) const;
00083     UDotErrIndex allocateUDotErr(const State& s, int nudoterr) const;
00084     EventTriggerByStageIndex allocateEventTriggersByStage(const State&, Stage, int ntriggers) const;
00085 
00086 
00087     // These return views on State shared global resources. The views
00088     // are private to this subsystem, but the global resources themselves
00089     // are not allocated until the *System* advances to stage Model.
00090     // Note that there is no subsystem equivalent of the State's "y"
00091     // vector because in general a subsystem's state variables will
00092     // not be contiguous. However, a subsystem's q's, u's, and z's
00093     // will all be contiguous within those arrays.
00094     const Vector& getQ(const State&) const;
00095     const Vector& getU(const State&) const;
00096     const Vector& getZ(const State&) const;
00097     const Vector& getQDot(const State&) const;
00098     const Vector& getUDot(const State&) const;
00099     const Vector& getZDot(const State&) const;
00100     const Vector& getQDotDot(const State&) const;
00101     const Vector& getQErr(const State&) const;
00102     const Vector& getUErr(const State&) const;
00103     const Vector& getUDotErr(const State&) const;
00104     const Vector& getMultipliers(const State&) const;
00105     const Vector& getEventTriggersByStage(const State&, Stage) const;
00106 
00107     // These return writable access to this subsystem's partition in the
00108     // State pool of continuous variables. These can be called at Stage::Model
00109     // or higher, and if necesary they invalidate the Position (q), Velocity (u),
00110     // or Dynamics (z) stage respectively.
00111     Vector& updQ(State&) const; // invalidates Stage::Position
00112     Vector& updU(State&) const; // invalidates Stage::Velocity
00113     Vector& updZ(State&) const; // invalidates Stage::Dynamics
00114 
00115     // For convenience.
00116     void setQ(State& s, const Vector& q) const {
00117         assert(q.size() == getNQ(s));
00118         updQ(s) = q;
00119     }
00120     void setU(State& s, const Vector& u) const {
00121         assert(u.size() == getNU(s));
00122         updU(s) = u;
00123     }
00124     void setZ(State& s, const Vector& z) const {
00125         assert(z.size() == getNZ(s));
00126         updZ(s) = z;
00127     }
00128 
00129     // These update the State cache which is mutable; hence, const State. They
00130     // can be called only if the previous stage has already been realized, e.g.,
00131     // updQDot() is allowed only while realizing the Velocity stage, requiring
00132     // that Position stage has already been realized.
00133     Vector& updQDot(const State&) const;
00134     Vector& updUDot(const State&) const;
00135     Vector& updZDot(const State&) const;
00136     Vector& updQDotDot(const State&) const;
00137     Vector& updQErr(const State&) const;
00138     Vector& updUErr(const State&) const;
00139     Vector& updUDotErr(const State&) const;
00140     Vector& updMultipliers(const State&) const;
00141     Vector& updEventTriggersByStage(const State&, Stage) const;
00142 
00143     // These pull out the State entries which belong exclusively to
00144     // this Subsystem. These variables and cache entries are available
00145     // as soon as this subsystem is at stage Model.
00146     Stage getStage(const State&) const;
00147     const AbstractValue& getDiscreteVariable(const State&, DiscreteVariableIndex) const;
00148     // State is *not* mutable here -- must have write access to change state variables.
00149     AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
00150     const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
00151     // State is mutable here.
00152     AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
00153 
00154     bool isCacheValueCurrent(const State&, CacheEntryIndex) const;
00155     void markCacheValueRealized(const State&, CacheEntryIndex) const;
00156 
00157     // Dimensions. These are valid at System Stage::Model while access to the various
00158     // arrays may have stricter requirements. Hence it is better to use these
00159     // routines than to get a reference to a Vector above and ask for its size().
00160 
00161     SystemQIndex getQStart      (const State&) const;
00162     int getNQ          (const State&) const;
00163     SystemUIndex getUStart      (const State&) const;
00164     int getNU          (const State&) const;
00165     SystemZIndex getZStart      (const State&) const;
00166     int getNZ          (const State&) const;
00167     SystemQErrIndex getQErrStart   (const State&) const;
00168     int getNQErr       (const State&) const;
00169     SystemUErrIndex getUErrStart   (const State&) const;
00170     int getNUErr       (const State&) const;
00171     SystemUDotErrIndex getUDotErrStart(const State&) const;
00172     int getNUDotErr    (const State&) const;
00173     SystemMultiplierIndex getMultipliersStart(const State&) const;
00174     int getNMultipliers(const State&) const;
00175     SystemEventTriggerByStageIndex   getEventTriggerStartByStage(const State&, Stage) const;
00176     int getNEventTriggersByStage(const State&, Stage) const;
00177 
00178     MeasureIndex adoptMeasure(Measure& m);
00179     Measure getMeasure(MeasureIndex) const;
00180     template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
00181     {   return Measure_<T>::getAs(getMeasure(mx));}
00182 
00183     bool isInSystem() const;
00184     bool isInSameSystem(const Subsystem& otherSubsystem) const;
00185 
00186     const System& getSystem() const;
00187     System&       updSystem();
00188 
00189     SubsystemIndex getMySubsystemIndex() const;
00190 
00191     // Internal use only
00192     const Subsystem& getOwnerSubsystemHandle() const;
00193     Subsystem& updOwnerSubsystemHandle();
00194     void setOwnerSubsystemHandle(Subsystem&);
00195     bool hasOwnerSubsystemHandle() const;
00196 
00197     void setSystem(System&, SubsystemIndex);
00198 
00199     class GutsRep;
00200     explicit Guts(GutsRep* r) : rep(r) { }
00201     bool                hasRep() const {return rep!=0;}
00202     const GutsRep& getRep() const {assert(rep); return *rep;}
00203     GutsRep&       updRep() const {assert(rep); return *rep;}
00204     void setRep(GutsRep& r) {assert(!rep); rep = &r;}
00205 
00206     bool subsystemTopologyHasBeenRealized() const;
00207     void invalidateSubsystemTopologyCache() const;
00208 
00209     // These are wrappers for the virtual methods defined below. They
00210     // are used to ensure good behavior.
00211 
00212     Subsystem::Guts* clone() const;
00213 
00214     // Realize this subsystem's part of the State from Stage-1 to Stage
00215     // for the indicated stage. After doing some checking, these routines
00216     // call the concrete subsystem's corresponding virtual method, and
00217     // on return they make sure the stage has been properly updated.
00218     // Note that these will do nothing if the Subsystem stage is already
00219     // at or greater than the indicated stage.
00220     void realizeSubsystemTopology    (State&) const;
00221     void realizeSubsystemModel       (State&) const;
00222     void realizeSubsystemInstance    (const State&) const;
00223     void realizeSubsystemTime        (const State&) const;
00224     void realizeSubsystemPosition    (const State&) const;
00225     void realizeSubsystemVelocity    (const State&) const;
00226     void realizeSubsystemDynamics    (const State&) const;
00227     void realizeSubsystemAcceleration(const State&) const;
00228     void realizeSubsystemReport      (const State&) const;
00229 
00230     // Calculate weights and tolerances.
00231 
00232     // Given the current values of our own position variables,
00233     // calculate a "unit weighting" for changes to these position
00234     // variables. 
00235     // @param[out] weights must be resizable or already the right size
00236     // @pre State must be realized to >= Stage::Position (this subsystem).
00237     void calcQUnitWeights(const State&, Vector& weights) const;
00238 
00239     // Given the current values of our own position variables,
00240     // calculate a "unit weighting" for changes to our velocity
00241     // variables.
00242     // @param[out] weights must be resizable or already the right size
00243     // @pre State must be realized to >= Stage::Position (this subsystem).
00244     void calcUUnitWeights(const State&, Vector& weights) const;
00245 
00246     // Given the current values of our own position variables,
00247     // calculate a "unit weighting" for changes to our auxiliary
00248     // variables.
00249     // @param[out] weights must be resizable or already the right size
00250     // @pre State must be realized to >= Stage::Position (this subsystem).
00251     void calcZUnitWeights(const State&, Vector& weights) const;
00252 
00253     // Calculate a "unit tolerance" for errors in each of this subsystem's
00254     // position-level constraints.
00255     // @param[out] tolerances must be resizable or already the right size
00256     // @pre State must be realized to >= Stage::Model (this subsystem).
00257     // @remark Tolerances are expected to be constant during a study; typically
00258     //         they just reflect the units in which the contraint equations
00259     //         are calculated, e.g. angles or lengths.
00260     void calcQErrUnitTolerances(const State&, Vector& tolerances) const;
00261 
00262     // Calculate a "unit tolerance" for errors in each of this subsystem's
00263     // velocity-level constraints.
00264     // @param[out] tolerances must be resizable or already the right size
00265     // @pre State must be realized to >= Stage::Model (this subsystem).
00266     // @remark Tolerances are expected to be constant during a study; typically
00267     //         they just reflect the units in which the contraint equations
00268     //         are calculated, e.g. angles/time or lengths/time.
00269     void calcUErrUnitTolerances(const State&, Vector& tolerances) const;
00270 
00271     // Generate decorative geometry computable at a specific stage. This will
00272     // throw an exception if this subsystem's state hasn't already been realized
00273     // to that stage. Note that the list is not inclusive -- you have to
00274     // request geometry from each stage to get all of it.
00275     // The generated geometry will be *appended* to the supplied output vector.
00276     void calcDecorativeGeometryAndAppend(const State&, Stage, std::vector<DecorativeGeometry>&) const;
00277     
00278     void createScheduledEvent(const State& state, EventId& eventId) const;
00279     void createTriggeredEvent(const State& state, EventId& eventId, EventTriggerByStageIndex& triggerFunctionIndex, Stage stage) const;
00280 
00281     // These methods are called by the corresponding methods of System.
00282     // Each subsystem is responsible for defining its own events, and
00283     // System then combines the information from them, and dispatches events
00284     // to the appropriate subsystems for handling when they occur.
00285     virtual void calcEventTriggerInfo(const State&, std::vector<System::EventTriggerInfo>&) const;
00286     virtual void calcTimeOfNextScheduledEvent(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00287     virtual void calcTimeOfNextScheduledReport(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00288     virtual void handleEvents(State&, Event::Cause, const std::vector<EventId>& eventIds,
00289         Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols,
00290         Stage& lowestModified, bool& shouldTerminate) const;
00291     virtual void reportEvents(const State&, Event::Cause, const std::vector<EventId>& eventIds) const;
00292 
00293 protected:
00294     // These virtual methods should be overridden in concrete Subsystems as
00295     // necessary. They should never be called directly; instead call the
00296     // wrapper routines above, which have the same name but without the "Impl"
00297     // (implementation) at the end.
00298     
00299     // The "realize..." wrappers will call the "realize...Impl" methods below
00300     // only when the current stage for the Subsystem is the one just prior
00301     // to the stage being realized. For example, realizeSubsystemVelocityImpl()
00302     // is called by realizeSubsystemVelocity() only when the passed-in State
00303     // shows this subsystem's stage to be exactly Stage::Position.
00304     //
00305     // The default implementations provided here do nothing. That means the
00306     // wrappers will simply check that the current stage is correct and
00307     // advance it if necessary.
00308 
00309     // The destructor is already virtual; see above.
00310 
00311     virtual Subsystem::Guts* cloneImpl() const = 0;
00312 
00313     virtual int realizeSubsystemTopologyImpl(State& s) const;
00314     virtual int realizeSubsystemModelImpl(State& s) const;
00315     virtual int realizeSubsystemInstanceImpl(const State& s) const;
00316     virtual int realizeSubsystemTimeImpl(const State& s) const;
00317     virtual int realizeSubsystemPositionImpl(const State& s) const;
00318     virtual int realizeSubsystemVelocityImpl(const State& s) const;
00319     virtual int realizeSubsystemDynamicsImpl(const State& s) const;
00320     virtual int realizeSubsystemAccelerationImpl(const State& s) const;
00321     virtual int realizeSubsystemReportImpl(const State& s) const;
00322 
00323     virtual int calcQUnitWeightsImpl(const State& s, Vector& weights) const;
00324     virtual int calcUUnitWeightsImpl(const State& s, Vector& weights) const;
00325     virtual int calcZUnitWeightsImpl(const State& s, Vector& weights) const;
00326     virtual int calcQErrUnitTolerancesImpl(const State& s, Vector& tolerances) const;
00327     virtual int calcUErrUnitTolerancesImpl(const State& s, Vector& tolerances) const;
00328     virtual int calcDecorativeGeometryAndAppendImpl
00329        (const State&, Stage, std::vector<DecorativeGeometry>&) const;
00330 
00331     void advanceToStage(const State& s, Stage g) const;
00332 
00333 private:
00334     // this is the only data member in the base class
00335     GutsRep* rep; // opaque implementation of Subsystem::Guts base class.
00336 
00337 friend class GutsRep;
00338 };
00339 
00340 } // namespace SimTK
00341 
00342 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_

Generated by  doxygen 1.6.2