Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Subsystem.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_H_
2 #define SimTK_SimTKCOMMON_SUBSYSTEM_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2006-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
27 #include "SimTKcommon/basics.h"
28 #include "SimTKcommon/Simmatrix.h"
31 
32 #include <cassert>
33 
34 namespace SimTK {
35 
36 class System;
37 
38 
62 public:
63  class Guts; // local; name is Subsystem::Guts
64  friend class Guts;
65 private:
66  // This is the only data member in this class. Also, any class derived from
67  // Subsystem must have *NO* data members at all (data goes in the Guts class).
68  Guts* guts;
69 public:
70  Subsystem() : guts(0) { } // an empty handle
71  Subsystem(const Subsystem&);
72  Subsystem& operator=(const Subsystem&);
73  ~Subsystem();
74 
75  const String& getName() const;
76  const String& getVersion() const;
77 
78  // These call the corresponding State method, supplying this Subsystem's
79  // SubsystemIndex. The returned indices are local to this Subsystem.
80  QIndex allocateQ(State&, const Vector& qInit) const;
81  UIndex allocateU(State&, const Vector& uInit) const;
82  ZIndex allocateZ(State&, const Vector& zInit) const;
83 
84  DiscreteVariableIndex allocateDiscreteVariable
85  (State&, Stage invalidates, AbstractValue* v) const;
86  DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
87  (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const;
88 
89  CacheEntryIndex allocateCacheEntry
90  (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
91  CacheEntryIndex allocateCacheEntry
92  (const State& state, Stage g, AbstractValue* v) const
93  { return allocateCacheEntry(state, g, g, v); }
94  CacheEntryIndex allocateLazyCacheEntry
95  (const State& state, Stage earliest, AbstractValue* v) const
96  { return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
97 
98  QErrIndex allocateQErr (const State&, int nqerr) const;
99  UErrIndex allocateUErr (const State&, int nuerr) const;
100  UDotErrIndex allocateUDotErr (const State&, int nudoterr) const;
101  EventTriggerByStageIndex allocateEventTriggersByStage
102  (const State&, Stage, int ntriggers) const;
103 
104  // These return views on State shared global resources. The views
105  // are private to this subsystem, but the global resources themselves
106  // are not allocated until the *System* advances to stage Model.
107  // Note that there is no subsystem equivalent of the State's "y"
108  // vector because in general a subsystem's state variables will
109  // not be contiguous. However, a subsystem's q's, u's, and z's
110  // will all be contiguous within those arrays.
111  const Vector& getQ(const State&) const;
112  const Vector& getU(const State&) const;
113  const Vector& getZ(const State&) const;
114  const Vector& getQDot(const State&) const;
115  const Vector& getUDot(const State&) const;
116  const Vector& getZDot(const State&) const;
117  const Vector& getQDotDot(const State&) const;
118  const Vector& getQErr(const State&) const;
119  const Vector& getUErr(const State&) const;
120  const Vector& getUDotErr(const State&) const;
121  const Vector& getMultipliers(const State&) const;
122  const Vector& getEventTriggersByStage(const State&, Stage) const;
123 
124  // These return writable access to this subsystem's partition in the
125  // State pool of continuous variables. These can be called at Stage::Model
126  // or higher, and if necesary they invalidate the Position (q), Velocity (u),
127  // or Dynamics (z) stage respectively.
128  Vector& updQ(State&) const; // invalidates Stage::Position
129  Vector& updU(State&) const; // invalidates Stage::Velocity
130  Vector& updZ(State&) const; // invalidates Stage::Dynamics
131 
132  // For convenience.
133  void setQ(State& s, const Vector& q) const {
134  assert(q.size() == getNQ(s));
135  updQ(s) = q;
136  }
137  void setU(State& s, const Vector& u) const {
138  assert(u.size() == getNU(s));
139  updU(s) = u;
140  }
141  void setZ(State& s, const Vector& z) const {
142  assert(z.size() == getNZ(s));
143  updZ(s) = z;
144  }
145 
146  // These update the State cache which is mutable; hence, const State. They
147  // can be called only if the previous stage has already been realized, e.g.,
148  // updQDot() is allowed only while realizing the Velocity stage, requiring
149  // that Position stage has already been realized.
150  Vector& updQDot(const State&) const;
151  Vector& updUDot(const State&) const;
152  Vector& updZDot(const State&) const;
153  Vector& updQDotDot(const State&) const;
154  Vector& updQErr(const State&) const;
155  Vector& updUErr(const State&) const;
156  Vector& updUDotErr(const State&) const;
157  Vector& updMultipliers(const State&) const;
158  Vector& updEventTriggersByStage(const State&, Stage) const;
159 
160  // These pull out the State entries which belong exclusively to
161  // this Subsystem. These variables and cache entries are available
162  // as soon as this subsystem is at stage Model.
163  Stage getStage(const State&) const;
164  const AbstractValue& getDiscreteVariable(const State& s, DiscreteVariableIndex dx) const;
165 
166  Real getDiscreteVarLastUpdateTime(const State& s, DiscreteVariableIndex dx) const
167  { return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
168  CacheEntryIndex getDiscreteVarUpdateIndex(const State& s, DiscreteVariableIndex dx) const
169  { return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
170  const AbstractValue& getDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
171  { return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
172  AbstractValue& updDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
173  { return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
174  bool isDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
175  { return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
176  void markDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
177  { return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
178 
179  // State is *not* mutable here -- must have write access to change state variables.
180  AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
181 
182  const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
183  // State is mutable here.
184  AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
185 
186  bool isCacheValueRealized(const State&, CacheEntryIndex) const;
187  void markCacheValueRealized(const State&, CacheEntryIndex) const;
188  void markCacheValueNotRealized(const State&, CacheEntryIndex) const;
189 
190  // Dimensions. These are valid at System Stage::Model while access to the
191  // various arrays may have stricter requirements. Hence it is better to use
192  // these routines than to get a reference to a Vector above and ask for
193  // its size().
194 
195  SystemQIndex getQStart (const State&) const;
196  int getNQ (const State&) const;
197  SystemUIndex getUStart (const State&) const;
198  int getNU (const State&) const;
199  SystemZIndex getZStart (const State&) const;
200  int getNZ (const State&) const;
201  SystemQErrIndex getQErrStart (const State&) const;
202  int getNQErr (const State&) const;
203  SystemUErrIndex getUErrStart (const State&) const;
204  int getNUErr (const State&) const;
205  SystemUDotErrIndex getUDotErrStart(const State&) const;
206  int getNUDotErr (const State&) const;
207  SystemMultiplierIndex getMultipliersStart (const State&) const;
208  int getNMultipliers (const State&) const;
209  SystemEventTriggerByStageIndex getEventTriggerStartByStage(const State&, Stage) const;
210  int getNEventTriggersByStage (const State&, Stage) const;
211 
212  bool isInSystem() const;
213  bool isInSameSystem(const Subsystem& otherSubsystem) const;
214 
215  const System& getSystem() const;
216  System& updSystem();
217 
218  SubsystemIndex getMySubsystemIndex() const;
219 
220  // Is this handle the owner of this rep? This is true if the
221  // handle is empty or if its rep points back here.
222  bool isOwnerHandle() const;
223  bool isEmptyHandle() const;
224 
225  // There can be multiple handles on the same Subsystem.
226  bool isSameSubsystem(const Subsystem& otherSubsystem) const;
227 
228  bool subsystemTopologyHasBeenRealized() const;
229  void invalidateSubsystemTopologyCache() const;
230 
231  // Add a new Measure to this Subsystem. This method is generally used by Measure
232  // constructors to install a newly-constructed Measure into its Subsystem.
233  MeasureIndex adoptMeasure(AbstractMeasure&);
234 
235  AbstractMeasure getMeasure(MeasureIndex) const;
236  template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
237  { return Measure_<T>::getAs(getMeasure(mx));}
238 
239  // dynamic_cast the returned reference to a reference to your concrete Guts
240  // class.
241  const Subsystem::Guts& getSubsystemGuts() const {assert(guts); return *guts;}
242  Subsystem::Guts& updSubsystemGuts() {assert(guts); return *guts;}
243 
244  // Put new Guts into this *empty* handle and take over ownership.
245  // If this handle is already in use, this routine will throw
246  // an exception.
247  void adoptSubsystemGuts(Subsystem::Guts* g);
248  void setSystem(System&, SubsystemIndex);
249 
250  explicit Subsystem(Subsystem::Guts* g) : guts(g) { }
251  bool hasGuts() const {return guts!=0;}
252 };
253 
254 } // namespace SimTK
255 
256 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_H_