Subsystem.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_H_
00002 #define SimTK_SimTKCOMMON_SUBSYSTEM_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/Measure.h"
00039 #include "SimTKcommon/internal/System.h"
00040 
00041 #include <cassert>
00042 
00043 namespace SimTK {
00044 
00045 class System;
00046 class DecorativeGeometry;
00047 class DefaultSystemSubsystemGuts;
00048 class ScheduledEventHandler;
00049 class ScheduledEventReporter;
00050 class TriggeredEventHandler;
00051 class TriggeredEventReporter;
00052 
00075 class SimTK_SimTKCOMMON_EXPORT Subsystem {
00076 public:
00077     class Guts; // local; name is Subsystem::Guts
00078     friend class Guts;
00079 private:
00080     // This is the only data member in this class. Also, any class derived from
00081     // Subsystem must have *NO* data members at all (data goes in the Guts class).
00082     Guts* guts;
00083 public:
00084     Subsystem() : guts(0) { } // an empty handle
00085     Subsystem(const Subsystem&);
00086     Subsystem& operator=(const Subsystem&);
00087     ~Subsystem();
00088 
00089     const String& getName()    const;
00090     const String& getVersion() const;
00091 
00092     // These call the corresponding State method, supplying this Subsystem's
00093     // SubsystemIndex. The returned indices are local to this Subsystem.
00094     QIndex allocateQ(State&, const Vector& qInit) const;
00095     UIndex allocateU(State&, const Vector& uInit) const;
00096     ZIndex allocateZ(State&, const Vector& zInit) const;
00097 
00098     DiscreteVariableIndex allocateDiscreteVariable
00099        (State&, Stage invalidates, AbstractValue* v) const;
00100     DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
00101        (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const; 
00102 
00103     CacheEntryIndex allocateCacheEntry
00104        (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
00105     CacheEntryIndex allocateCacheEntry   
00106        (const State& state, Stage g, AbstractValue* v) const 
00107     {   return allocateCacheEntry(state, g, g, v); }
00108     CacheEntryIndex allocateLazyCacheEntry   
00109        (const State& state, Stage earliest, AbstractValue* v) const 
00110     {   return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
00111 
00112     QErrIndex allocateQErr         (const State&, int nqerr) const;
00113     UErrIndex allocateUErr         (const State&, int nuerr) const;
00114     UDotErrIndex allocateUDotErr      (const State&, int nudoterr) const;
00115     EventTriggerByStageIndex allocateEventTriggersByStage
00116        (const State&, Stage, int ntriggers) const;
00117 
00118     // These return views on State shared global resources. The views
00119     // are private to this subsystem, but the global resources themselves
00120     // are not allocated until the *System* advances to stage Model.
00121     // Note that there is no subsystem equivalent of the State's "y"
00122     // vector because in general a subsystem's state variables will
00123     // not be contiguous. However, a subsystem's q's, u's, and z's
00124     // will all be contiguous within those arrays.
00125     const Vector& getQ(const State&) const;
00126     const Vector& getU(const State&) const;
00127     const Vector& getZ(const State&) const;
00128     const Vector& getQDot(const State&) const;
00129     const Vector& getUDot(const State&) const;
00130     const Vector& getZDot(const State&) const;
00131     const Vector& getQDotDot(const State&) const;
00132     const Vector& getQErr(const State&) const;
00133     const Vector& getUErr(const State&) const;
00134     const Vector& getUDotErr(const State&) const;
00135     const Vector& getMultipliers(const State&) const;
00136     const Vector& getEventTriggersByStage(const State&, Stage) const;
00137 
00138     // These return writable access to this subsystem's partition in the
00139     // State pool of continuous variables. These can be called at Stage::Model
00140     // or higher, and if necesary they invalidate the Position (q), Velocity (u),
00141     // or Dynamics (z) stage respectively.
00142     Vector& updQ(State&) const; // invalidates Stage::Position
00143     Vector& updU(State&) const; // invalidates Stage::Velocity
00144     Vector& updZ(State&) const; // invalidates Stage::Dynamics
00145 
00146     // For convenience.
00147     void setQ(State& s, const Vector& q) const {
00148         assert(q.size() == getNQ(s));
00149         updQ(s) = q;
00150     }
00151     void setU(State& s, const Vector& u) const {
00152         assert(u.size() == getNU(s));
00153         updU(s) = u;
00154     }
00155     void setZ(State& s, const Vector& z) const {
00156         assert(z.size() == getNZ(s));
00157         updZ(s) = z;
00158     }
00159 
00160     // These update the State cache which is mutable; hence, const State. They
00161     // can be called only if the previous stage has already been realized, e.g.,
00162     // updQDot() is allowed only while realizing the Velocity stage, requiring
00163     // that Position stage has already been realized.
00164     Vector& updQDot(const State&) const;
00165     Vector& updUDot(const State&) const;
00166     Vector& updZDot(const State&) const;
00167     Vector& updQDotDot(const State&) const;
00168     Vector& updQErr(const State&) const;
00169     Vector& updUErr(const State&) const;
00170     Vector& updUDotErr(const State&) const;
00171     Vector& updMultipliers(const State&) const;
00172     Vector& updEventTriggersByStage(const State&, Stage) const;
00173 
00174     // These pull out the State entries which belong exclusively to
00175     // this Subsystem. These variables and cache entries are available
00176     // as soon as this subsystem is at stage Model.
00177     Stage getStage(const State&) const;
00178     const AbstractValue& getDiscreteVariable(const State& s, DiscreteVariableIndex dx) const;
00179 
00180     Real getDiscreteVarLastUpdateTime(const State& s, DiscreteVariableIndex dx) const
00181     {   return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
00182     CacheEntryIndex getDiscreteVarUpdateIndex(const State& s, DiscreteVariableIndex dx) const
00183     {   return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
00184     const AbstractValue& getDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00185     {   return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00186     AbstractValue& updDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00187     {   return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00188     bool isDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
00189     {   return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00190     void markDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
00191     {   return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00192 
00193     // State is *not* mutable here -- must have write access to change state variables.
00194     AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
00195 
00196     const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
00197     // State is mutable here.
00198     AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
00199 
00200     bool isCacheValueRealized(const State&, CacheEntryIndex) const;
00201     void markCacheValueRealized(const State&, CacheEntryIndex) const;
00202 
00203     // Dimensions. These are valid at System Stage::Model while access to the 
00204     // various arrays may have stricter requirements. Hence it is better to use
00205     // these routines than to get a reference to a Vector above and ask for 
00206     // its size().
00207 
00208     SystemQIndex getQStart      (const State&) const;
00209     int getNQ          (const State&) const;
00210     SystemUIndex getUStart      (const State&) const;
00211     int getNU          (const State&) const;
00212     SystemZIndex getZStart      (const State&) const;
00213     int getNZ          (const State&) const;
00214     SystemQErrIndex getQErrStart   (const State&) const;
00215     int getNQErr       (const State&) const;
00216     SystemUErrIndex getUErrStart   (const State&) const;
00217     int getNUErr       (const State&) const;
00218     SystemUDotErrIndex getUDotErrStart(const State&) const;
00219     int getNUDotErr    (const State&) const;
00220     SystemMultiplierIndex getMultipliersStart (const State&) const;
00221     int getNMultipliers     (const State&) const;
00222     SystemEventTriggerByStageIndex getEventTriggerStartByStage(const State&, Stage) const;
00223     int getNEventTriggersByStage   (const State&, Stage) const;
00224 
00225     bool isInSystem() const;
00226     bool isInSameSystem(const Subsystem& otherSubsystem) const;
00227 
00228     const System& getSystem() const;
00229     System&       updSystem();
00230 
00231     SubsystemIndex getMySubsystemIndex() const;
00232 
00233     // Is this handle the owner of this rep? This is true if the
00234     // handle is empty or if its rep points back here.
00235     bool isOwnerHandle() const;
00236     bool isEmptyHandle() const;
00237 
00238     // There can be multiple handles on the same Subsystem.
00239     bool isSameSubsystem(const Subsystem& otherSubsystem) const;
00240 
00241     bool subsystemTopologyHasBeenRealized() const;
00242     void invalidateSubsystemTopologyCache() const;
00243 
00244     // Add a new Measure to this Subsystem. This method is generally used by Measure
00245     // constructors to install a newly-constructed Measure into its Subsystem.
00246     MeasureIndex adoptMeasure(AbstractMeasure&);
00247 
00248     AbstractMeasure getMeasure(MeasureIndex) const;
00249     template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
00250     {   return Measure_<T>::getAs(getMeasure(mx));}
00251 
00252     // dynamic_cast the returned reference to a reference to your concrete Guts
00253     // class.
00254     const Subsystem::Guts& getSubsystemGuts() const {assert(guts); return *guts;}
00255     Subsystem::Guts&       updSubsystemGuts()       {assert(guts); return *guts;}
00256 
00257     // Put new Guts into this *empty* handle and take over ownership.
00258     // If this handle is already in use, this routine will throw
00259     // an exception.
00260     void adoptSubsystemGuts(Subsystem::Guts* g);
00261     void setSystem(System&, SubsystemIndex);
00262 
00263     explicit Subsystem(Subsystem::Guts* g) : guts(g) { }
00264     bool hasGuts() const {return guts!=0;}
00265 };
00266 
00267 
00268 
00274 class SimTK_SimTKCOMMON_EXPORT DefaultSystemSubsystem : public Subsystem {
00275 public:
00276     explicit DefaultSystemSubsystem(System& sys);
00277     void addEventHandler(ScheduledEventHandler* handler);
00278     void addEventHandler(TriggeredEventHandler* handler);
00279     void addEventReporter(ScheduledEventReporter* handler) const;
00280     void addEventReporter(TriggeredEventReporter* handler) const;
00281     EventId createEventId(SubsystemIndex subsys, const State& state) const;
00282     void findSubsystemEventIds
00283        (SubsystemIndex subsys, const State& state, 
00284         const Array_<EventId>& allEvents, 
00285         Array_<EventId>& eventsForSubsystem) const;
00286 private:
00287     const DefaultSystemSubsystemGuts& getGuts() const;
00288     DefaultSystemSubsystemGuts& updGuts();
00289 };
00290 
00291 
00292 } // namespace SimTK
00293 
00294 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_H_

Generated on Thu Aug 12 16:37:27 2010 for SimTKcore by  doxygen 1.6.1