Simbody  3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
StateImpl.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_STATE_IMPL_H_
2 #define SimTK_SimTKCOMMON_STATE_IMPL_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) 2005-14 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: Peter Eastman *
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  // Hide from Doxygen
32 
33 // This header is logically an extension of State.h and is intended to be
34 // included from within State.h and nowhere else.
35 
36 namespace SimTK {
37 
38 // These local classes
39 // DiscreteVarInfo
40 // CacheVarInfo
41 // EventInfo
42 // contain the information needed for each discrete variable and cache entry,
43 // including a reference to its current value and everything needed to
44 // understand its dependencies, as well as information for each Event allocated
45 // by a Subsystem.
46 //
47 // These are intended as elements in an allocation stack as described above,
48 // so it is expected that they will get reaallocated, copied, and destructed
49 // during allocation as the Array_ gets resized from time to time. However, the
50 // discrete variable and cache entry *values* must remain in a fixed location in
51 // memory once allocated, because callers are permitted to retain references to
52 // these values once they have been allocated. So pointers to the AbstractValues
53 // are kept in these objects, and only the pointers are copied around. That
54 // means the actual value object will not be deleted by the destructor; be sure
55 // to do that explicitly in the higher-level destructor or you'll have a nasty
56 // leak.
57 
58 //==============================================================================
59 // DISCRETE VAR INFO
60 //==============================================================================
61 class DiscreteVarInfo {
62 public:
63  DiscreteVarInfo()
64  : allocationStage(Stage::Empty), invalidatedStage(Stage::Empty),
65  value(0), timeLastUpdated(NaN) {}
66 
67  DiscreteVarInfo(Stage allocation, Stage invalidated, AbstractValue* v)
68  : allocationStage(allocation), invalidatedStage(invalidated),
69  autoUpdateEntry(), value(v), timeLastUpdated(NaN)
70  { assert(isReasonable()); }
71 
72  // Default copy constructor, copy assignment, destructor are shallow.
73 
74  // Use this to make this entry contain a *copy* of the source value.
75  // If the destination already has a value, the new value must be
76  // assignment compatible.
77  DiscreteVarInfo& deepAssign(const DiscreteVarInfo& src) {
78  assert(src.isReasonable());
79 
80  allocationStage = src.allocationStage;
81  invalidatedStage = src.invalidatedStage;
82  autoUpdateEntry = src.autoUpdateEntry;
83  if (value) *value = *src.value;
84  else value = src.value->clone();
85  timeLastUpdated = src.timeLastUpdated;
86  return *this;
87  }
88 
89  // For use in the containing class's destructor.
90  void deepDestruct() {delete value; value=0;}
91  const Stage& getAllocationStage() const {return allocationStage;}
92 
93  // Exchange value pointers (should be from this dv's update cache entry).
94  void swapValue(Real updTime, AbstractValue*& other)
95  { std::swap(value, other); timeLastUpdated=updTime; }
96 
97  const AbstractValue& getValue() const {assert(value); return *value;}
98  Real getTimeLastUpdated() const
99  { assert(value); return timeLastUpdated; }
100  AbstractValue& updValue(Real updTime)
101  { assert(value); timeLastUpdated=updTime; return *value; }
102 
103  const Stage& getInvalidatedStage() const {return invalidatedStage;}
104  CacheEntryIndex getAutoUpdateEntry() const {return autoUpdateEntry;}
105  void setAutoUpdateEntry(CacheEntryIndex cx) {autoUpdateEntry = cx;}
106 
107 private:
108  // These are fixed at construction.
109  Stage allocationStage;
110  Stage invalidatedStage;
111  CacheEntryIndex autoUpdateEntry;
112 
113  // These change at run time.
114  AbstractValue* value;
115  Real timeLastUpdated;
116 
117  bool isReasonable() const
118  { return (allocationStage==Stage::Topology
119  || allocationStage==Stage::Model)
120  && (invalidatedStage > allocationStage)
121  && (value != 0); }
122 };
123 
124 
125 
126 //==============================================================================
127 // CACHE ENTRY INFO
128 //==============================================================================
129 class CacheEntryInfo {
130 public:
131  CacheEntryInfo()
132  : allocationStage(Stage::Empty), dependsOnStage(Stage::Empty),
133  computedByStage(Stage::Empty), value(0), versionWhenLastComputed(-1) {}
134 
135  CacheEntryInfo
136  (Stage allocation, Stage dependsOn, Stage computedBy, AbstractValue* v)
137  : allocationStage(allocation), dependsOnStage(dependsOn),
138  computedByStage(computedBy), value(v), versionWhenLastComputed(0)
139  { assert(isReasonable()); }
140 
141  bool isCurrent(const Stage& current, const StageVersion versions[]) const
142  { if (current >= computedByStage) return true;
143  if (current < dependsOnStage) return false;
144  return versions[dependsOnStage] == versionWhenLastComputed;}
145 
146  StageVersion getVersionWhenLastComputed() const
147  { return versionWhenLastComputed; }
148 
149  // These affect only the explicit "last computed" flag which does not fully
150  // determine whether the value is current; see isCurrent() above.
151  void invalidate() {versionWhenLastComputed = 0;}
152  void markAsComputed(const StageVersion versions[])
153  { versionWhenLastComputed = versions[dependsOnStage];}
154 
155  // Default copy constructor, copy assignment, destructor are shallow.
156 
157  // Use this to make this entry contain a *copy* of the source value.
158  CacheEntryInfo& deepAssign(const CacheEntryInfo& src) {
159  assert(src.isReasonable());
160 
161  allocationStage = src.allocationStage;
162  dependsOnStage = src.dependsOnStage;
163  computedByStage = src.computedByStage;
164  associatedVar = src.associatedVar;
165  if (value) *value = *src.value;
166  else value = src.value->clone();
167  versionWhenLastComputed = src.versionWhenLastComputed;
168  return *this;
169  }
170 
171  // For use in the containing class's destructor.
172  void deepDestruct() {delete value; value=0;}
173  const Stage& getAllocationStage() const {return allocationStage;}
174 
175  // Exchange values with a discrete variable (presumably this
176  // cache entry has been determined to be that variable's update
177  // entry but we're not checking here).
178  void swapValue(Real updTime, DiscreteVarInfo& dv)
179  { dv.swapValue(updTime, value); }
180  const AbstractValue& getValue() const {assert(value); return *value;}
181  AbstractValue& updValue() {assert(value); return *value;}
182 
183  const Stage& getDependsOnStage() const {return dependsOnStage;}
184  const Stage& getComputedByStage() const {return computedByStage;}
185  DiscreteVariableIndex getAssociatedVar() const {return associatedVar;}
186  void setAssociatedVar(DiscreteVariableIndex dx) {associatedVar=dx;}
187 private:
188  // These are fixed at construction.
189  Stage allocationStage;
190  Stage dependsOnStage;
191  Stage computedByStage;
192  DiscreteVariableIndex associatedVar; // if this is an auto-update entry
193 
194  // These change at run time.
195  AbstractValue* value;
196  StageVersion versionWhenLastComputed;//version of Stage dependsOn
197 
198  bool isReasonable() const
199  { return ( allocationStage==Stage::Topology
200  || allocationStage==Stage::Model
201  || allocationStage==Stage::Instance)
202  && (computedByStage >= dependsOnStage)
203  && (value != 0)
204  && (versionWhenLastComputed >= 0); }
205 };
206 
207 
208 
209 //==============================================================================
210 // TRIGGER INFO
211 //==============================================================================
212 class TriggerInfo {
213 public:
214  TriggerInfo()
215  : allocationStage(Stage::Empty), firstIndex(-1), nslots(0) {}
216 
217  TriggerInfo(Stage allocation, int index, int n)
218  : allocationStage(allocation), firstIndex(index), nslots(n)
219  { assert(isReasonable()); assert(n>0);}
220 
221  // Default copy constructor, copy assignment, destructor are fine since
222  // there is no heap object owned here.
223 
224  int getFirstIndex() const {return firstIndex;}
225  int getNumSlots() const {return nslots;}
226 
227  // These the the "virtual" methods required by template methods elsewhere.
228  TriggerInfo& deepAssign(const TriggerInfo& src)
229  { return operator=(src); }
230  void deepDestruct() {}
231  const Stage& getAllocationStage() const {return allocationStage;}
232 private:
233  // These are fixed at construction.
234  Stage allocationStage;
235  int firstIndex;
236  int nslots;
237 
238  bool isReasonable() const {
239  return ( allocationStage==Stage::Topology
240  || allocationStage==Stage::Model
241  || allocationStage==Stage::Instance);
242  }
243 };
244 
245 
246 
247 //==============================================================================
248 // CONTINUOUS VAR INFO
249 //==============================================================================
250 // Used for q, u, and z (in separate stacks).
251 // These accumulate default values for this subsystem's use of shared
252 // global state variables. After the System is advanced to Stage::Model,
253 // the state will allocate those globals and copy the initial
254 // values stored here into them. Some of these are allocated at Topology
255 // stage, and some at Model stage. If Model stage is invalidated, variables
256 // allocated then are forgotten while the ones allocated at Topology stage
257 // remain.
258 class ContinuousVarInfo {
259 public:
260  ContinuousVarInfo() : allocationStage(Stage::Empty), firstIndex(-1) {}
261 
262  ContinuousVarInfo(Stage allocation,
263  int index, // QIndex, UIndex, or ZIndex
264  const Vector& initVals,
265  const Vector& varWeights=Vector())
266  : allocationStage(allocation), firstIndex(index), initialValues(initVals)
267  { assert(isReasonable());
268  assert(varWeights.size()==0 || varWeights.size()==initVals.size());
269  assert(weightsAreOK(varWeights));
270  if (varWeights.size()) weights=varWeights;
271  else weights=Vector(initVals.size(), Real(1));
272  }
273 
274  int getFirstIndex() const {return firstIndex;}
275  int getNumVars() const {return initialValues.size();}
276  const Vector& getInitialValues() const {return initialValues;}
277  const Vector& getWeights() const {return weights;}
278 
279  // Default copy constructor, copy assignment, destructor are fine since
280  // there is no heap object owned here.
281 
282  // These the the "virtual" methods required by template methods elsewhere.
283  ContinuousVarInfo& deepAssign(const ContinuousVarInfo& src)
284  { return operator=(src); }
285  void deepDestruct() {}
286  const Stage& getAllocationStage() const {return allocationStage;}
287 private:
288  // These are fixed at construction.
289  Stage allocationStage;
290  int firstIndex; // a QIndex, UIndex, or ZIndex
291  Vector initialValues;
292  Vector weights; // only used for u and z
293 
294  static bool weightsAreOK(const Vector& wts) {
295  for (int i=0; i<wts.size(); ++i)
296  if (wts[i] <= 0) return false;
297  return true;
298  }
299 
300  bool isReasonable() const {
301  return ( allocationStage==Stage::Topology
302  || allocationStage==Stage::Model);
303  }
304 };
305 
306 //==============================================================================
307 // CONSTRAINT ERR INFO
308 //==============================================================================
309 // Used for qerr, uerr, and udoterr.
310 class ConstraintErrInfo {
311 public:
312  ConstraintErrInfo() : allocationStage(Stage::Empty), firstIndex(-1) {}
313 
314  ConstraintErrInfo(Stage allocation,
315  int index, // QErr, UErr, or UDotErrIndex
316  int nerr,
317  const Vector& varWeights=Vector())
318  : allocationStage(allocation), firstIndex(index)
319  { assert(isReasonable());
320  assert(varWeights.size()==0 || varWeights.size()==nerr);
321  assert(weightsAreOK(varWeights));
322  if (varWeights.size()) weights=varWeights;
323  else weights=Vector(nerr, Real(1));
324  }
325 
326  int getFirstIndex() const {return firstIndex;}
327  int getNumErrs() const {return weights.size();}
328  const Vector& getWeights() const {return weights;}
329 
330  // Default copy constructor, copy assignment, destructor are fine since
331  // there is no heap object owned here.
332 
333  // These the the "virtual" methods required by template methods elsewhere.
334  ConstraintErrInfo& deepAssign(const ConstraintErrInfo& src)
335  { return operator=(src); }
336  void deepDestruct() {}
337  const Stage& getAllocationStage() const {return allocationStage;}
338 private:
339  // These are fixed at construction.
340  Stage allocationStage;
341  int firstIndex; // a QErrIndex, UErrIndex, or UDotErrIndex
342  Vector weights; // only used for u and z
343 
344  static bool weightsAreOK(const Vector& wts) {
345  for (int i=0; i<wts.size(); ++i)
346  if (wts[i] <= 0) return false;
347  return true;
348  }
349 
350  bool isReasonable() const {
351  return ( allocationStage==Stage::Topology
352  || allocationStage==Stage::Model
353  || allocationStage==Stage::Instance);
354  }
355 };
356 
357 
358 
359 //==============================================================================
360 // PER SUBSYSTEM INFO
361 //==============================================================================
362 // This internal utility class is used to capture all the information needed for
363 // a single subsystem within the StateImpl.
364 class PerSubsystemInfo {
365 public:
366  PerSubsystemInfo() : currentStage(Stage::Empty) {initialize();}
367  PerSubsystemInfo(const String& n, const String& v)
368  : name(n), version(v), currentStage(Stage::Empty) {initialize();}
369 
370  // Everything will properly clean itself up except for the AbstractValues
371  // stored in the discrete variable and cache entry arrays. Be sure to
372  // delete those prior to allowing the arrays themselves to destruct.
373  ~PerSubsystemInfo() {
374  clearAllStacks();
375  }
376 
377  // Copy constructor copies all variables but cache only through
378  // Instance stage. Note that this must be done in conjunction with
379  // copying the whole state or our global resource indices will
380  // be nonsense.
381  PerSubsystemInfo(const PerSubsystemInfo& src) : currentStage(Stage::Empty) {
382  initialize();
383  copyFrom(src, Stage::Instance);
384  }
385 
386  PerSubsystemInfo& operator=(const PerSubsystemInfo& src) {
387  // destination is already initialized; copyFrom() will try
388  // to reuse space and will properly clean up unused stuff
389  if (&src != this)
390  copyFrom(src, Stage::Instance);
391  return *this;
392  }
393 
394  // Back up to the stage just before g if this subsystem thinks
395  // it is already at g or beyond. Note that we may be backing up
396  // over many stages here. Careful: invalidating the stage
397  // for a subsystem must also invalidate the same stage for all
398  // the other subsystems and the system as a whole but we don't
399  // take care of that here. Also, you can't invalidate Stage::Empty.
400  void invalidateStageJustThisSubsystem(Stage g) {
401  assert(g > Stage::Empty);
402  restoreToStage(g.prev());
403  }
404 
405  // Advance from stage g-1 to stage g. This is called at the end
406  // of realize(g). You can't use this to "advance" to Stage::Empty.
407  // It is a fatal error if the current stage isn't g-1.
408  void advanceToStage(Stage g) const {
409  assert(g > Stage::Empty);
410  assert(currentStage == g.prev());
411 
412  // This validates whatever the current version number is of Stage g.
413  currentStage = g;
414  }
415 
416 
417  void clearReferencesToModelStageGlobals() {
418  qstart.invalidate(); ustart.invalidate();
419  zstart.invalidate();
420  q.clear(); u.clear(); z.clear();
421  uWeights.clear(); zWeights.clear();
422  qdot.clear(); udot.clear(); zdot.clear(); qdotdot.clear();
423  }
424 
425  void clearReferencesToInstanceStageGlobals() {
426  // These are late-allocated state variables.
427  qerrWeights.clear(); uerrWeights.clear();
428 
429  // These are all mutable cache entries.
430  qerrstart.invalidate();uerrstart.invalidate();udoterrstart.invalidate();
431  qerr.clear();uerr.clear();udoterr.clear();multipliers.clear();
432 
433  for (int j=0; j<Stage::NValid; ++j) {
434  triggerstart[j].invalidate();
435  triggers[j].clear();
436  }
437  }
438 
439  QIndex getNextQIndex() const {
440  if (qInfo.empty()) return QIndex(0);
441  const ContinuousVarInfo& last = qInfo.back();
442  return QIndex(last.getFirstIndex()+last.getNumVars());
443  }
444  UIndex getNextUIndex() const {
445  if (uInfo.empty()) return UIndex(0);
446  const ContinuousVarInfo& last = uInfo.back();
447  return UIndex(last.getFirstIndex()+last.getNumVars());
448  }
449  ZIndex getNextZIndex() const {
450  if (zInfo.empty()) return ZIndex(0);
451  const ContinuousVarInfo& last = zInfo.back();
452  return ZIndex(last.getFirstIndex()+last.getNumVars());
453  }
454 
455  QErrIndex getNextQErrIndex() const {
456  if (qerrInfo.empty()) return QErrIndex(0);
457  const ConstraintErrInfo& last = qerrInfo.back();
458  return QErrIndex(last.getFirstIndex()+last.getNumErrs());
459  }
460  UErrIndex getNextUErrIndex() const {
461  if (uerrInfo.empty()) return UErrIndex(0);
462  const ConstraintErrInfo& last = uerrInfo.back();
463  return UErrIndex(last.getFirstIndex()+last.getNumErrs());
464  }
465  UDotErrIndex getNextUDotErrIndex() const {
466  if (udoterrInfo.empty()) return UDotErrIndex(0);
467  const ConstraintErrInfo& last = udoterrInfo.back();
468  return UDotErrIndex(last.getFirstIndex()+last.getNumErrs());
469  }
470  DiscreteVariableIndex getNextDiscreteVariableIndex() const {
471  return DiscreteVariableIndex(discreteInfo.size());
472  }
473  CacheEntryIndex getNextCacheEntryIndex() const {
474  return CacheEntryIndex(cacheInfo.size());
475  }
476  EventTriggerByStageIndex getNextEventTriggerByStageIndex(Stage g) const {
477  if (triggerInfo[g].empty()) return EventTriggerByStageIndex(0);
478  const TriggerInfo& last = triggerInfo[g].back();
479  return EventTriggerByStageIndex
480  (last.getFirstIndex()+last.getNumSlots());
481  }
482 
483 
484  String name;
485  String version;
486 
487  // DEFINITIONS //
488 
489  // State variables (continuous or discrete) can be defined (allocated)
490  // during realization of Topology or Model stages. Cache entries,
491  // constraint error slots, and event trigger slots can be defined during
492  // realization of Topology, Model, or Instance stages. No further
493  // allocations are allowed. Then, when one of these stages is invalidated,
494  // all the definitions that occurred during realization of that stage must
495  // be forgotten.
496  //
497  // To do that the allocation entries are stored in arrays which are really
498  // stacks, with definitions pushed onto the ends as the stage is advanced
499  // and popped off the ends as the stage is reduced.
500 
501  // Topology and Model stage definitions.
502  Array_<ContinuousVarInfo> qInfo, uInfo, zInfo;
503  Array_<DiscreteVarInfo> discreteInfo;
504 
505  // Topology, Model, and Instance stage definitions.
506  mutable Array_<ConstraintErrInfo> qerrInfo, uerrInfo, udoterrInfo;
507  mutable Array_<TriggerInfo> triggerInfo[Stage::NValid];
508  mutable Array_<CacheEntryInfo> cacheInfo;
509 
510  // GLOBAL RESOURCE ALLOCATIONS //
511 
512  // These are our own private views into partitions of the global
513  // state and cache entries of the same names. The State will assign
514  // contiguous blocks to this subsystem when the *System* stage is raised
515  // to Model or Instance stage, and they are invalidated whenever that
516  // stage is invalidated. The starting indices are filled in here at
517  // the time the views are built.
518 
519  // Model stage global resources and views into them.
520  SystemQIndex qstart;
521  SystemUIndex ustart;
522  SystemZIndex zstart;
523  Vector q, u, z;
524  Vector uWeights, zWeights;
525 
526  mutable Vector qdot, udot, zdot, qdotdot;
527 
528  // Instance stage global resources and views into them.
529  Vector qerrWeights, uerrWeights;
530 
531  // Note that multipliers just use the same indices as udoterr.
532  mutable SystemQErrIndex qerrstart;
533  mutable SystemUErrIndex uerrstart;
534  mutable SystemUDotErrIndex udoterrstart;
535  mutable SystemEventTriggerByStageIndex triggerstart[Stage::NValid];
536 
537  mutable Vector qerr, uerr;
538 
539  mutable Vector udoterr, multipliers; // same size and partioning
540  mutable Vector triggers[Stage::NValid];
541 
542  // The currentStage is the highest stage of this subsystem that is valid,
543  // meaning that it has been realized since the last change to any variable
544  // that might affect it. All stages less than currentStage are also valid,
545  // and all higher stages are invalid.
546  // Each stage has a "stage version" which is like a serial number that is
547  // bumped every time the stage is invalidated by a variable change. Cache
548  // entries that are calculated from a particular stage version can record
549  // the version number to allow a quick check later -- if the current version
550  // of a cache entry's dependsOn stage is different than the one stored with
551  // the cache entry, then that cache entry cannot be valid.
552  mutable Stage currentStage;
553  mutable StageVersion stageVersions[Stage::NValid];
554 
555 private:
556  // This is for use in constructors and for resetting an existing State into
557  // its just-constructed condition.
558  void initialize() {
559  clearAllStacks();
560  qstart.invalidate();ustart.invalidate();zstart.invalidate();
561  qerrstart.invalidate();uerrstart.invalidate();udoterrstart.invalidate();
562  for (int j=0; j<Stage::NValid; ++j) {
563  triggerstart[j].invalidate();
564  stageVersions[j] = 1; // never 0
565  }
566  currentStage = Stage::Empty;
567  }
568 
569  // Manage allocation stacks.
570 
571  void clearContinuousVars();
572  void clearConstraintErrs();
573  void clearDiscreteVars();
574  void clearEventTriggers(int g);
575  void clearCache();
576 
577  void clearAllStacks();
578 
579  void popContinuousVarsBackToStage(const Stage& g);
580  void popDiscreteVarsBackToStage(const Stage& g);
581  void popConstraintErrsBackToStage(const Stage& g);
582  void popCacheBackToStage(const Stage& g);
583  void popEventTriggersBackToStage(const Stage& g);
584 
585  void popAllStacksBackToStage(const Stage& g);
586 
587  // Call once each for qInfo, uInfo, zInfo.
588  void copyContinuousVarInfoThroughStage
589  (const Array_<ContinuousVarInfo>& src, const Stage& g,
590  Array_<ContinuousVarInfo>& dest);
591 
592  void copyDiscreteVarsThroughStage
593  (const Array_<DiscreteVarInfo>& src, const Stage& g);
594 
595  // Call once each for qerrInfo, uerrInfo, udoterrInfo.
596  void copyConstraintErrInfoThroughStage
597  (const Array_<ConstraintErrInfo>& src, const Stage& g,
598  Array_<ConstraintErrInfo>& dest);
599 
600  void copyCacheThroughStage
601  (const Array_<CacheEntryInfo>& src, const Stage& g);
602 
603  void copyEventsThroughStage
604  (const Array_<TriggerInfo>& src, const Stage& g,
605  Array_<TriggerInfo>& dest);
606 
607  void copyAllStacksThroughStage(const PerSubsystemInfo& src, const Stage& g);
608 
609  // Restore this subsystem to the way it last was at realize(g) for a given
610  // Stage g; that is, invalidate all stages > g. Allocations will be
611  // forgotten as Instance, Model, and Topology stages are invalidated.
612  void restoreToStage(Stage g);
613 
614  // Utility which makes "this" a copy of the source subsystem exactly as it
615  // was after being realized to stage maxStage. If maxStage >= Model then
616  // all the subsystem-private state variables will be copied, but only
617  // cached computations up through maxStage come through. We clear
618  // our references to global variables regardless -- those will have to
619  // be repaired at the System (State global) level.
620  void copyFrom(const PerSubsystemInfo& src, Stage maxStage);
621 };
622 
623 
624 //==============================================================================
625 // STATE IMPL
626 //==============================================================================
627 
628 class StateImpl {
629 public:
630  StateImpl()
631  : t(NaN), currentSystemStage(Stage::Empty) {initializeStageVersions();}
632 
633  // We'll do the copy constructor and assignment explicitly here
634  // to get tight control over what's allowed.
635  StateImpl(const StateImpl& src);
636 
637  StateImpl& operator=(const StateImpl& src);
638 
639  ~StateImpl() {} // default destructor
640 
641  // Copies all the variables but not the cache.
642  StateImpl* clone() const {return new StateImpl(*this);}
643 
644  const Stage& getSystemStage() const {return currentSystemStage;}
645  Stage& updSystemStage() const {return currentSystemStage;} // mutable
646 
647 
648  const PerSubsystemInfo& getSubsystem(int subsystem) const {
649  SimTK_INDEXCHECK(subsystem, (int)subsystems.size(),
650  "StateImpl::getSubsystem()");
651  return subsystems[subsystem];
652  }
653 
654  PerSubsystemInfo& updSubsystem(int subsystem) {
655  SimTK_INDEXCHECK(subsystem, (int)subsystems.size(),
656  "StateImpl::updSubsystem()");
657  return subsystems[subsystem];
658  }
659 
660  const Stage& getSubsystemStage(int subsystem) const {
661  return subsystems[subsystem].currentStage;
662  }
663  Stage& updSubsystemStage(int subsystem) const {
664  return subsystems[subsystem].currentStage; // mutable
665  }
666 
667  const StageVersion* getSubsystemStageVersions(int subsystem) const {
668  return subsystems[subsystem].stageVersions;
669  }
670 
671  // Back up the System stage just before stg if it thinks
672  // it is already at stg or beyond. Note that we may be backing up
673  // over many stages here. Careful: invalidating the stage
674  // for the system must also invalidate the same stage for all
675  // the subsystems (because we trash the shared resource pool
676  // here if we back up earlier than Stage::Model) but we don't
677  // take care of that here. Also, you can't invalidate Stage::Empty.
678  void invalidateJustSystemStage(Stage stg);
679 
680  // Advance the System stage from stg-1 to stg. It is a fatal error if
681  // we're not already at stg-1, and you can't advance to Stage::Empty.
682  // Also, you can't advance the system to stg unless ALL subsystems have
683  // already gotten there.
684  void advanceSystemToStage(Stage stg) const;
685 
686  void setNumSubsystems(int i) {
687  assert(i >= 0);
688  subsystems.clear();
689  subsystems.resize(i);
690  }
691 
692  void initializeSubsystem
693  (SubsystemIndex i, const String& name, const String& version) {
694  updSubsystem(i).name = name;
695  updSubsystem(i).version = version;
696  }
697 
698  SubsystemIndex addSubsystem(const String& name, const String& version) {
699  const SubsystemIndex sx(subsystems.size());
700  subsystems.push_back(PerSubsystemInfo(name,version));
701  return sx;
702  }
703 
704  int getNumSubsystems() const {return (int)subsystems.size();}
705 
706  const String& getSubsystemName(SubsystemIndex subsys) const {
707  return subsystems[subsys].name;
708  }
709  const String& getSubsystemVersion(SubsystemIndex subsys) const {
710  return subsystems[subsys].version;
711  }
712 
713  // Make sure the stage is no higher than g-1 for *any* subsystem and
714  // hence for the system stage also. TODO: this should be more selective.
715  void invalidateAll(Stage g) {
716  invalidateJustSystemStage(g);
717  for (SubsystemIndex i(0); i<(int)subsystems.size(); ++i)
718  subsystems[i].invalidateStageJustThisSubsystem(g);
719  }
720 
721  // Make sure the stage is no higher than g-1 for *any* subsystem and
722  // hence for the system stage also. Same as invalidateAll() except this
723  // requires only const access and can't be used for g below Instance.
724  void invalidateAllCacheAtOrAbove(Stage g) const {
726  "StateImpl::invalidateAllCacheAtOrAbove()");
727 
728  // We promise not to hurt this State; get non-const access just so
729  // we can call these methods.
730  StateImpl* mthis = const_cast<StateImpl*>(this);
731  mthis->invalidateJustSystemStage(g);
732  for (SubsystemIndex i(0); i<(int)subsystems.size(); ++i)
733  mthis->subsystems[i].invalidateStageJustThisSubsystem(g);
734  }
735 
736  // Move the stage for a particular subsystem from g-1 to g. No other
737  // subsystems are affected, nor the global system stage.
738  void advanceSubsystemToStage(SubsystemIndex subsys, Stage g) const {
739  subsystems[subsys].advanceToStage(g);
740  // We don't automatically advance the System stage even if this brings
741  // ALL the subsystems up to stage g.
742  }
743 
744  // We don't expect State entry allocations to be performance critical so
745  // we'll keep error checking on even in Release mode.
746 
747  QIndex allocateQ(SubsystemIndex subsys, const Vector& qInit) {
748  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys), Stage::Model,
749  "StateImpl::allocateQ()");
750  // We are currently realizing the next stage.
751  const Stage allocStage = getSubsystemStage(subsys).next();
752  PerSubsystemInfo& ss = subsystems[subsys];
753  const QIndex nxt(ss.getNextQIndex());
754  ss.qInfo.push_back(ContinuousVarInfo(allocStage,nxt,qInit,Vector()));
755  return nxt;
756  }
757 
758  UIndex allocateU(SubsystemIndex subsys, const Vector& uInit) {
759  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys), Stage::Model,
760  "StateImpl::allocateU()");
761  const Stage allocStage = getSubsystemStage(subsys).next();
762  PerSubsystemInfo& ss = subsystems[subsys];
763  const UIndex nxt(ss.getNextUIndex());
764  ss.uInfo.push_back(ContinuousVarInfo(allocStage,nxt,uInit,Vector()));
765  return nxt;
766  }
767  ZIndex allocateZ(SubsystemIndex subsys, const Vector& zInit) {
768  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys), Stage::Model,
769  "StateImpl::allocateZ()");
770  const Stage allocStage = getSubsystemStage(subsys).next();
771  PerSubsystemInfo& ss = subsystems[subsys];
772  const ZIndex nxt(ss.getNextZIndex());
773  ss.zInfo.push_back(ContinuousVarInfo(allocStage,nxt,zInit,Vector()));
774  return nxt;
775  }
776 
777  QErrIndex allocateQErr(SubsystemIndex subsys, int nqerr) const {
778  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys), Stage::Instance,
779  "StateImpl::allocateQErr()");
780  const Stage allocStage = getSubsystemStage(subsys).next();
781  const PerSubsystemInfo& ss = subsystems[subsys];
782  const QErrIndex nxt(ss.getNextQErrIndex());
783  ss.qerrInfo.push_back(ConstraintErrInfo(allocStage,nxt,nqerr,Vector()));
784  return nxt;
785  }
786  UErrIndex allocateUErr(SubsystemIndex subsys, int nuerr) const {
787  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys),
788  Stage::Instance,"StateImpl::allocateUErr()");
789  const Stage allocStage = getSubsystemStage(subsys).next();
790  const PerSubsystemInfo& ss = subsystems[subsys];
791  const UErrIndex nxt(ss.getNextUErrIndex());
792  ss.uerrInfo.push_back(ConstraintErrInfo(allocStage,nxt,nuerr,Vector()));
793  return nxt;
794  }
795  UDotErrIndex allocateUDotErr(SubsystemIndex subsys, int nudoterr) const {
796  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys), Stage::Instance,
797  "StateImpl::allocateUDotErr()");
798  const Stage allocStage = getSubsystemStage(subsys).next();
799  const PerSubsystemInfo& ss = subsystems[subsys];
800  const UDotErrIndex nxt(ss.getNextUDotErrIndex());
801  ss.udoterrInfo.push_back
802  (ConstraintErrInfo(allocStage,nxt,nudoterr,Vector()));
803  return nxt;
804  }
805  EventTriggerByStageIndex allocateEventTrigger
806  (SubsystemIndex subsys, Stage g, int nt) const {
807  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys), Stage::Instance,
808  "StateImpl::allocateEventTrigger()");
809  const Stage allocStage = getSubsystemStage(subsys).next();
810  const PerSubsystemInfo& ss = subsystems[subsys];
811  const EventTriggerByStageIndex
812  nxt(ss.getNextEventTriggerByStageIndex(g));
813  ss.triggerInfo[g].push_back(TriggerInfo(allocStage,nxt,nt));
814  return nxt;
815  }
816 
817  // Topology- and Model-stage State variables can only be added during
818  // construction; that is, while stage <= Topology. Other entries can be
819  // added while stage < Model.
820  DiscreteVariableIndex allocateDiscreteVariable
821  (SubsystemIndex subsys, Stage invalidates, AbstractValue* vp)
822  {
824  invalidates, Stage::HighestRuntime,
825  "StateImpl::allocateDiscreteVariable()");
826 
827  const Stage maxAcceptable = (invalidates <= Stage::Model
829  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys),
830  maxAcceptable.next(), "StateImpl::allocateDiscreteVariable()");
831 
832  const Stage allocStage = getSubsystemStage(subsys).next();
833  PerSubsystemInfo& ss = subsystems[subsys];
834  const DiscreteVariableIndex nxt(ss.getNextDiscreteVariableIndex());
835  ss.discreteInfo.push_back
836  (DiscreteVarInfo(allocStage,invalidates,vp));
837  return nxt;
838  }
839 
840  // Cache entries can be allocated while stage < Instance.
841  CacheEntryIndex allocateCacheEntry
842  (SubsystemIndex subsys, Stage dependsOn, Stage computedBy,
843  AbstractValue* vp) const
844  {
846  dependsOn, Stage::HighestRuntime,
847  "StateImpl::allocateCacheEntry()");
848  SimTK_STAGECHECK_RANGE_ALWAYS(dependsOn, computedBy, Stage::Infinity,
849  "StateImpl::allocateCacheEntry()");
850  SimTK_STAGECHECK_LT_ALWAYS(getSubsystemStage(subsys),
851  Stage::Instance, "StateImpl::allocateCacheEntry()");
852 
853  const Stage allocStage = getSubsystemStage(subsys).next();
854  const PerSubsystemInfo& ss = subsystems[subsys];
855  const CacheEntryIndex nxt(ss.getNextCacheEntryIndex());
856  ss.cacheInfo.push_back
857  (CacheEntryInfo(allocStage, dependsOn, computedBy, vp)); //mutable
858  return nxt;
859  }
860 
861  // Allocate a discrete variable and a corresponding cache entry for
862  // updating it, and connect them together.
863  DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
864  (SubsystemIndex subsys, Stage invalidates, AbstractValue* vp,
865  Stage updateDependsOn)
866  {
867  const DiscreteVariableIndex dx =
868  allocateDiscreteVariable(subsys,invalidates,vp->clone());
869  const CacheEntryIndex cx =
870  allocateCacheEntry(subsys,updateDependsOn,Stage::Infinity,vp);
871 
872  PerSubsystemInfo& ss = subsystems[subsys];
873  DiscreteVarInfo& dvinfo = ss.discreteInfo[dx];
874  CacheEntryInfo& ceinfo = ss.cacheInfo[cx];
875  dvinfo.setAutoUpdateEntry(cx);
876  ceinfo.setAssociatedVar(dx);
877  return dx;
878  }
879 
880  // State dimensions for shared continuous variables.
881 
882  int getNY() const {
883  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
884  "StateImpl::getNY()");
885  return y.size();
886  }
887 
888  SystemYIndex getQStart() const {
889  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
890  "StateImpl::getQStart()");
891  return SystemYIndex(0); // q's come first
892  }
893  int getNQ() const {
894  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
895  "StateImpl::getNQ()");
896  return q.size();
897  }
898 
899  SystemYIndex getUStart() const {
900  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
901  "StateImpl::getUStart()");
902  return SystemYIndex(q.size()); // u's come right after q's
903  }
904  int getNU() const {
905  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
906  "StateImpl::getNU()");
907  return u.size();
908  }
909 
910  SystemYIndex getZStart() const {
911  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
912  "StateImpl::getZStart()");
913  return SystemYIndex(q.size() + u.size()); // q,u, then z
914  }
915  int getNZ() const {
916  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
917  "StateImpl::getNZ()");
918  return z.size();
919  }
920 
921  int getNYErr() const {
922  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
923  "StateImpl::getNYErr()");
924  return yerr.size();
925  }
926 
927  SystemYErrIndex getQErrStart() const {
928  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
929  "StateImpl::getQErrStart()");
930  return SystemYErrIndex(0); // qerr's come first
931  }
932  int getNQErr() const {
933  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
934  "StateImpl::getNQErr()");
935  return qerr.size();
936  }
937 
938  SystemYErrIndex getUErrStart() const {
939  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
940  "StateImpl::getUErrStart()");
941  return SystemYErrIndex(qerr.size()); // uerr's follow qerrs
942  }
943  int getNUErr() const {
944  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
945  "StateImpl::getNUErr()");
946  return uerr.size();
947  }
948 
949  // UDot errors are independent of qerr & uerr.
950  // This is used for multipliers also.
951  int getNUDotErr() const {
952  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
953  "StateImpl::getNUDotErr()");
954  return udoterr.size();
955  }
956 
957  int getNEventTriggers() const {
958  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
959  "StateImpl::getNEventTriggers()");
960  return allTriggers.size();
961  }
962 
963  SystemEventTriggerIndex getEventTriggerStartByStage(Stage g) const {
964  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
965  "StateImpl::getEventTriggerStartByStage()");
966  int nxt = 0;
967  for (int j=0; j<g; ++j)
968  nxt += triggers[j].size();
969  return SystemEventTriggerIndex(nxt); // g starts where g-1 leaves off
970  }
971 
972  int getNEventTriggersByStage(Stage g) const {
973  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
974  "StateImpl::getNEventTriggersByStage()");
975  return triggers[g].size();
976  }
977 
978  // Subsystem dimensions.
979 
980  SystemQIndex getQStart(SubsystemIndex subsys) const {
981  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
982  "StateImpl::getQStart(subsys)");
983  return getSubsystem(subsys).qstart;
984  }
985  int getNQ(SubsystemIndex subsys) const {
986  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
987  "StateImpl::getNQ(subsys)");
988  return getSubsystem(subsys).q.size();
989  }
990 
991  SystemUIndex getUStart(SubsystemIndex subsys) const {
992  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
993  "StateImpl::getUStart(subsys)");
994  return getSubsystem(subsys).ustart;
995  }
996  int getNU(SubsystemIndex subsys) const {
997  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
998  "StateImpl::getNU(subsys)");
999  return getSubsystem(subsys).u.size();
1000  }
1001 
1002  SystemZIndex getZStart(SubsystemIndex subsys) const {
1003  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1004  "StateImpl::getZStart(subsys)");
1005  return getSubsystem(subsys).zstart;
1006  }
1007  int getNZ(SubsystemIndex subsys) const {
1008  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1009  "StateImpl::getNZ(subsys)");
1010  return getSubsystem(subsys).z.size();
1011  }
1012 
1013  SystemQErrIndex getQErrStart(SubsystemIndex subsys) const {
1014  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1015  "StateImpl::getQErrStart(subsys)");
1016  return getSubsystem(subsys).qerrstart;
1017  }
1018  int getNQErr(SubsystemIndex subsys) const {
1019  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1020  "StateImpl::getNQErr(subsys)");
1021  return getSubsystem(subsys).qerr.size();
1022  }
1023 
1024  SystemUErrIndex getUErrStart(SubsystemIndex subsys) const {
1025  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1026  "StateImpl::getUErrStart(subsys)");
1027  return getSubsystem(subsys).uerrstart;
1028  }
1029  int getNUErr(SubsystemIndex subsys) const {
1030  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1031  "StateImpl::getNUErr(subsys)");
1032  return getSubsystem(subsys).uerr.size();
1033  }
1034 
1035  // These are used for multipliers also.
1036  SystemUDotErrIndex getUDotErrStart(SubsystemIndex subsys) const {
1037  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1038  "StateImpl::getUDotErrStart(subsys)");
1039  return getSubsystem(subsys).udoterrstart;
1040  }
1041  int getNUDotErr(SubsystemIndex subsys) const {
1042  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1043  "StateImpl::getNUDotErr(subsys)");
1044  return getSubsystem(subsys).udoterr.size();
1045  }
1046 
1047  SystemEventTriggerByStageIndex getEventTriggerStartByStage
1048  (SubsystemIndex subsys, Stage g) const {
1049  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1050  "StateImpl::getEventTriggerStartByStage(subsys)");
1051  return getSubsystem(subsys).triggerstart[g];
1052  }
1053 
1054  int getNEventTriggersByStage(SubsystemIndex subsys, Stage g) const {
1055  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1056  "StateImpl::getNEventTriggersByStage(subsys)");
1057  return getSubsystem(subsys).triggers[g].size();
1058  }
1059 
1060  // Per-subsystem access to the global shared variables.
1061 
1062  const Vector& getQ(SubsystemIndex subsys) const {
1063  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1064  "StateImpl::getQ(subsys)");
1065  return getSubsystem(subsys).q;
1066  }
1067  const Vector& getU(SubsystemIndex subsys) const {
1068  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1069  "StateImpl::getU(subsys)");
1070  return getSubsystem(subsys).u;
1071  }
1072  const Vector& getZ(SubsystemIndex subsys) const {
1073  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1074  "StateImpl::getZ(subsys)");
1075  return getSubsystem(subsys).z;
1076  }
1077 
1078  const Vector& getUWeights(SubsystemIndex subsys) const {
1079  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1080  "StateImpl::getUWeights(subsys)");
1081  return getSubsystem(subsys).uWeights;
1082  }
1083  const Vector& getZWeights(SubsystemIndex subsys) const {
1084  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1085  "StateImpl::getZWeights(subsys)");
1086  return getSubsystem(subsys).zWeights;
1087  }
1088 
1089  const Vector& getQDot(SubsystemIndex subsys) const {
1090  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1091  "StateImpl::getQDot(subsys)");
1092  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Velocity,
1093  "StateImpl::getQDot(subsys)");
1094  return getSubsystem(subsys).qdot;
1095  }
1096  const Vector& getUDot(SubsystemIndex subsys) const {
1097  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1098  "StateImpl::getUDot(subsys)");
1099  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Acceleration,
1100  "StateImpl::getUDot(subsys)");
1101  return getSubsystem(subsys).udot;
1102  }
1103  const Vector& getZDot(SubsystemIndex subsys) const {
1104  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1105  "StateImpl::getZDot(subsys)");
1106  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Dynamics,
1107  "StateImpl::getZDot(subsys)");
1108  return getSubsystem(subsys).zdot;
1109  }
1110  const Vector& getQDotDot(SubsystemIndex subsys) const {
1111  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1112  "StateImpl::getQDotDot(subsys)");
1113  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Acceleration,
1114  "StateImpl::getQDotDot(subsys)");
1115  return getSubsystem(subsys).qdotdot;
1116  }
1117 
1118  Vector& updQ(SubsystemIndex subsys) {
1119  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1120  "StateImpl::updQ(subsys)");
1121  invalidateAll(Stage::Position);
1122  return updSubsystem(subsys).q;
1123  }
1124  Vector& updU(SubsystemIndex subsys) {
1125  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1126  "StateImpl::updU(subsys)");
1127  invalidateAll(Stage::Velocity);
1128  return updSubsystem(subsys).u;
1129  }
1130  Vector& updZ(SubsystemIndex subsys) {
1131  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1132  "StateImpl::updZ(subsys)");
1133  invalidateAll(Stage::Dynamics);
1134  return updSubsystem(subsys).z;
1135  }
1136 
1137  Vector& updUWeights(SubsystemIndex subsys) {
1138  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1139  "StateImpl::updUWeights(subsys)");
1140  invalidateAll(Stage::Report);
1141  return updSubsystem(subsys).uWeights;
1142  }
1143  Vector& updZWeights(SubsystemIndex subsys) {
1144  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1145  "StateImpl::updZWeights(subsys)");
1146  invalidateAll(Stage::Report);
1147  return updSubsystem(subsys).zWeights;
1148  }
1149 
1150  // These are mutable so the routines are const.
1151 
1152  Vector& updQDot(SubsystemIndex subsys) const {
1153  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1154  "StateImpl::updQDot(subsys)");
1155  return getSubsystem(subsys).qdot;
1156  }
1157  Vector& updUDot(SubsystemIndex subsys) const {
1158  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1159  "StateImpl::updUDot(subsys)");
1160  return getSubsystem(subsys).udot;
1161  }
1162  Vector& updZDot(SubsystemIndex subsys) const {
1163  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1164  "StateImpl::updZDot(subsys)");
1165  return getSubsystem(subsys).zdot;
1166  }
1167  Vector& updQDotDot(SubsystemIndex subsys) const {
1168  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1169  "StateImpl::updQDotDot(subsys)");
1170  return getSubsystem(subsys).qdotdot;
1171  }
1172 
1173 
1174  const Vector& getQErr(SubsystemIndex subsys) const {
1175  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1176  "StateImpl::getQErr(subsys)");
1177  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Position,
1178  "StateImpl::getQErr(subsys)");
1179  return getSubsystem(subsys).qerr;
1180  }
1181  const Vector& getUErr(SubsystemIndex subsys) const {
1182  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1183  "StateImpl::getUErr(subsys)");
1184  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Velocity,
1185  "StateImpl::getUErr(subsys)");
1186  return getSubsystem(subsys).uerr;
1187  }
1188 
1189  const Vector& getQErrWeights(SubsystemIndex subsys) const {
1190  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1191  "StateImpl::getQErrWeights(subsys)");
1192  return getSubsystem(subsys).qerrWeights;
1193  }
1194  const Vector& getUErrWeights(SubsystemIndex subsys) const {
1195  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1196  "StateImpl::getUErrWeights(subsys)");
1197  return getSubsystem(subsys).uerrWeights;
1198  }
1199 
1200  const Vector& getUDotErr(SubsystemIndex subsys) const {
1201  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1202  "StateImpl::getUDotErr(subsys)");
1203  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Acceleration,
1204  "StateImpl::getUDotErr(subsys)");
1205  return getSubsystem(subsys).udoterr;
1206  }
1207  const Vector& getMultipliers(SubsystemIndex subsys) const {
1208  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1209  "StateImpl::getMultipliers(subsys)");
1210  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Acceleration,
1211  "StateImpl::getMultipliers(subsys)");
1212  return getSubsystem(subsys).multipliers;
1213  }
1214 
1215  const Vector& getEventTriggersByStage(SubsystemIndex subsys, Stage g) const {
1216  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1217  "StateImpl::getEventTriggersByStage(subsys)");
1218  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), g,
1219  "StateImpl::getEventTriggersByStage(subsys)");
1220  return getSubsystem(subsys).triggers[g];
1221  }
1222 
1223  Vector& updQErr(SubsystemIndex subsys) const {
1224  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1225  "StateImpl::updQErr(subsys)");
1226  return getSubsystem(subsys).qerr;
1227  }
1228  Vector& updUErr(SubsystemIndex subsys) const {
1229  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1230  "StateImpl::updUErr(subsys)");
1231  return getSubsystem(subsys).uerr;
1232  }
1233 
1234  Vector& updQErrWeights(SubsystemIndex subsys) {
1235  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1236  "StateImpl::updQErrWeights(subsys)");
1237  invalidateAll(Stage::Position);
1238  return updSubsystem(subsys).qerrWeights;
1239  }
1240  Vector& updUErrWeights(SubsystemIndex subsys) {
1241  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1242  "StateImpl::updUErrWeights(subsys)");
1243  invalidateAll(Stage::Velocity);
1244  return updSubsystem(subsys).uerrWeights;
1245  }
1246 
1247  Vector& updUDotErr(SubsystemIndex subsys) const {
1248  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1249  "StateImpl::updUDotErr(subsys)");
1250  return getSubsystem(subsys).udoterr;
1251  }
1252  Vector& updMultipliers(SubsystemIndex subsys) const {
1253  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1254  "StateImpl::updMultipliers(subsys)");
1255  return getSubsystem(subsys).multipliers;
1256  }
1257  Vector& updEventTriggersByStage(SubsystemIndex subsys, Stage g) const {
1258  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1259  "StateImpl::updEventTriggersByStage(subsys)");
1260  return getSubsystem(subsys).triggers[g];
1261  }
1262 
1263  // Direct access to the global shared state and cache entries.
1264  // Time is allocated in Stage::Topology, State in Stage::Model, and
1265  // Cache in Stage::Instance.
1266 
1267  const Real& getTime() const {
1268  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Topology,
1269  "StateImpl::getTime()");
1270  return t;
1271  }
1272 
1273  const Vector& getY() const {
1274  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1275  "StateImpl::getY()");
1276  return y;
1277  }
1278 
1279  const Vector& getQ() const {
1280  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1281  "StateImpl::getQ()");
1282  return q;
1283  }
1284 
1285  const Vector& getU() const {
1286  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1287  "StateImpl::getU()");
1288  return u;
1289  }
1290 
1291  const Vector& getZ() const {
1292  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1293  "StateImpl::getZ()");
1294  return z;
1295  }
1296 
1297  const Vector& getUWeights() const {
1298  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1299  "StateImpl::getUWeights()");
1300  return uWeights;
1301  }
1302 
1303  const Vector& getZWeights() const {
1304  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1305  "StateImpl::getZWeights()");
1306  return zWeights;
1307  }
1308 
1309  // You can call these as long as stage >= allocation stage, but the
1310  // stage will be backed up if necessary to one stage prior to the invalidated stage.
1311  Real& updTime() { // Back to Stage::Time-1
1312  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Topology,
1313  "StateImpl::updTime()");
1314  invalidateAll(Stage::Time);
1315  return t;
1316  }
1317 
1318  Vector& updY() { // Back to Stage::Position-1
1319  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1320  "StateImpl::updY()");
1321  invalidateAll(Stage::Position);
1322  return y;
1323  }
1324 
1325  Vector& updQ() { // Stage::Position-1
1326  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1327  "StateImpl::updQ()");
1328  invalidateAll(Stage::Position);
1329  return q;
1330  }
1331 
1332  Vector& updU() { // Stage::Velocity-1
1333  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1334  "StateImpl::updU()");
1335  invalidateAll(Stage::Velocity);
1336  return u;
1337  }
1338 
1339  Vector& updZ() { // Stage::Dynamics-1
1340  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1341  "StateImpl::updZ()");
1342  invalidateAll(Stage::Dynamics);
1343  return z;
1344  }
1345 
1346  Vector& updUWeights() { // Invalidates Report stage only
1347  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1348  "StateImpl::updUWeights()");
1349  invalidateAll(Stage::Report);
1350  return uWeights;
1351  }
1352 
1353  Vector& updZWeights() { // Invalidates Report stage only
1354  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1355  "StateImpl::updZWeights()");
1356  invalidateAll(Stage::Dynamics);
1357  return zWeights;
1358  }
1359 
1360  // These cache entries you can get at their "computedBy" stages.
1361  const Vector& getYDot() const {
1362  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Acceleration,
1363  "StateImpl::getYDot()");
1364  return ydot;
1365  }
1366 
1367  const Vector& getQDot() const {
1368  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Velocity,
1369  "StateImpl::getQDot()");
1370  return qdot;
1371  }
1372 
1373  const Vector& getZDot() const {
1374  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Dynamics,
1375  "StateImpl::getZDot()");
1376  return zdot;
1377  }
1378 
1379  const Vector& getUDot() const {
1380  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Acceleration,
1381  "StateImpl::getUDot()");
1382  return udot;
1383  }
1384 
1385  const Vector& getQDotDot() const {
1386  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Acceleration,
1387  "StateImpl::getQDotDot()");
1388  return qdotdot;
1389  }
1390 
1391  // Cache updates are allowed any time after they have been allocated.
1392  Vector& updYDot() const {
1393  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1394  "StateImpl::updYDot()");
1395  return ydot;
1396  }
1397 
1398  Vector& updQDot() const {
1399  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1400  "StateImpl::updQDot()");
1401  return qdot;
1402  }
1403 
1404  Vector& updUDot() const {
1405  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1406  "StateImpl::updUDot()");
1407  return udot;
1408  }
1409 
1410  Vector& updZDot() const {
1411  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1412  "StateImpl::updZDot()");
1413  return zdot;
1414  }
1415 
1416  Vector& updQDotDot() const {
1417  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Model,
1418  "StateImpl::updQDotDot()");
1419  return qdotdot;
1420  }
1421 
1422 
1423  const Vector& getYErr() const {
1424  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Velocity,
1425  "StateImpl::getYErr()");
1426  return yerr;
1427  }
1428 
1429  const Vector& getQErr() const {
1430  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Position,
1431  "StateImpl::getQErr()");
1432  return qerr;
1433  }
1434  const Vector& getUErr() const {
1435  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Velocity,
1436  "StateImpl::getUErr()");
1437  return uerr;
1438  }
1439 
1440  const Vector& getQErrWeights() const {
1441  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1442  "StateImpl::getQErrWeights()");
1443  return qerrWeights;
1444  }
1445  const Vector& getUErrWeights() const {
1446  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1447  "StateImpl::getUErrWeights()");
1448  return uerrWeights;
1449  }
1450 
1451  const Vector& getUDotErr() const {
1452  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Acceleration,
1453  "StateImpl::getUDotErr()");
1454  return udoterr;
1455  }
1456  const Vector& getMultipliers() const {
1457  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Acceleration,
1458  "StateImpl::getMultipliers()");
1459  return multipliers;
1460  }
1461 
1462  Vector& updYErr() const {
1463  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1464  "StateImpl::updYErr()");
1465  return yerr;
1466  }
1467  Vector& updQErr() const{
1468  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1469  "StateImpl::updQErr()");
1470  return qerr;
1471  }
1472  Vector& updUErr() const{
1473  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1474  "StateImpl::updUErr()");
1475  return uerr;
1476  }
1477 
1478  Vector& updQErrWeights() {
1479  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1480  "StateImpl::updQErrWeights()");
1481  invalidateAll(Stage::Position);
1482  return qerrWeights;
1483  }
1484  Vector& updUErrWeights() {
1485  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1486  "StateImpl::updUErrWeights()");
1487  invalidateAll(Stage::Velocity);
1488  return uerrWeights;
1489  }
1490 
1491  Vector& updUDotErr() const{
1492  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1493  "StateImpl::updUDotErr()");
1494  return udoterr;
1495  }
1496  Vector& updMultipliers() const{
1497  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1498  "StateImpl::updMultipliers()");
1499  return multipliers;
1500  }
1501 
1502  const Vector& getEventTriggers() const {
1503  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Acceleration,
1504  "StateImpl::getEventTriggers()");
1505  return allTriggers;
1506  }
1507  const Vector& getEventTriggersByStage(Stage g) const {
1508  SimTK_STAGECHECK_GE(getSystemStage(), g,
1509  "StateImpl::getEventTriggersByStage()");
1510  return triggers[g];
1511  }
1512 
1513  // These are mutable; hence 'const'.
1514  Vector& updEventTriggers() const {
1515  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1516  "StateImpl::updEventTriggers()");
1517  return allTriggers;
1518  }
1519  Vector& updEventTriggersByStage(Stage g) const {
1520  SimTK_STAGECHECK_GE(getSystemStage(), Stage::Instance,
1521  "StateImpl::updEventTriggersByStage()");
1522  return triggers[g];
1523  }
1524 
1525  CacheEntryIndex getDiscreteVarUpdateIndex
1526  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1527  const PerSubsystemInfo& ss = subsystems[subsys];
1528  SimTK_INDEXCHECK(index,(int)ss.discreteInfo.size(),
1529  "StateImpl::getDiscreteVarUpdateIndex()");
1530  const DiscreteVarInfo& dv = ss.discreteInfo[index];
1531  return dv.getAutoUpdateEntry();
1532  }
1533 
1534  Stage getDiscreteVarAllocationStage
1535  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1536  const PerSubsystemInfo& ss = subsystems[subsys];
1537  SimTK_INDEXCHECK(index,(int)ss.discreteInfo.size(),
1538  "StateImpl::getDiscreteVarAllocationStage()");
1539  const DiscreteVarInfo& dv = ss.discreteInfo[index];
1540  return dv.getAllocationStage();
1541  }
1542 
1543  Stage getDiscreteVarInvalidatesStage
1544  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1545  const PerSubsystemInfo& ss = subsystems[subsys];
1546  SimTK_INDEXCHECK(index,(int)ss.discreteInfo.size(),
1547  "StateImpl::getDiscreteVarInvalidatesStage()");
1548  const DiscreteVarInfo& dv = ss.discreteInfo[index];
1549  return dv.getInvalidatedStage();
1550  }
1551 
1552  // You can access at any time a variable that was allocated during
1553  // realizeTopology(), but don't access others until you have done
1554  // realizeModel().
1555  const AbstractValue&
1556  getDiscreteVariable(SubsystemIndex subsys, DiscreteVariableIndex index) const {
1557  const PerSubsystemInfo& ss = subsystems[subsys];
1558 
1559  SimTK_INDEXCHECK(index,(int)ss.discreteInfo.size(),
1560  "StateImpl::getDiscreteVariable()");
1561  const DiscreteVarInfo& dv = ss.discreteInfo[index];
1562 
1563  if (dv.getAllocationStage() > Stage::Topology) {
1564  SimTK_STAGECHECK_GE(getSubsystemStage(subsys), Stage::Model,
1565  "StateImpl::getDiscreteVariable()");
1566  }
1567 
1568  return dv.getValue();
1569  }
1570  Real getDiscreteVarLastUpdateTime(SubsystemIndex subsys, DiscreteVariableIndex index) const {
1571  const PerSubsystemInfo& ss = subsystems[subsys];
1572  SimTK_INDEXCHECK(index,(int)ss.discreteInfo.size(),
1573  "StateImpl::getDiscreteVarLastUpdateTime()");
1574  const DiscreteVarInfo& dv = ss.discreteInfo[index];
1575  return dv.getTimeLastUpdated();
1576  }
1577 
1578  const AbstractValue& getDiscreteVarUpdateValue
1579  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1580  const CacheEntryIndex cx = getDiscreteVarUpdateIndex(subsys,index);
1581  SimTK_ERRCHK2(cx.isValid(), "StateImpl::getDiscreteVarUpdateValue()",
1582  "Subsystem %d has a discrete variable %d but it does not have an"
1583  " associated update cache variable.", (int)subsys, (int)index);
1584  return getCacheEntry(subsys, cx);
1585  }
1586  AbstractValue& updDiscreteVarUpdateValue
1587  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1588  const CacheEntryIndex cx = getDiscreteVarUpdateIndex(subsys,index);
1589  SimTK_ERRCHK2(cx.isValid(), "StateImpl::updDiscreteVarUpdateValue()",
1590  "Subsystem %d has a discrete variable %d but it does not have an"
1591  " associated update cache variable.", (int)subsys, (int)index);
1592  return updCacheEntry(subsys, cx);
1593  }
1594  bool isDiscreteVarUpdateValueRealized
1595  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1596  const CacheEntryIndex cx = getDiscreteVarUpdateIndex(subsys,index);
1597  SimTK_ERRCHK2(cx.isValid(), "StateImpl::isDiscreteVarUpdateValueRealized()",
1598  "Subsystem %d has a discrete variable %d but it does not have an"
1599  " associated update cache variable.", (int)subsys, (int)index);
1600  return isCacheValueRealized(subsys, cx);
1601  }
1602  void markDiscreteVarUpdateValueRealized
1603  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1604  const CacheEntryIndex cx = getDiscreteVarUpdateIndex(subsys,index);
1605  SimTK_ERRCHK2(cx.isValid(),
1606  "StateImpl::markDiscreteVarUpdateValueRealized()",
1607  "Subsystem %d has a discrete variable %d but it does not have an"
1608  " associated update cache variable.", (int)subsys, (int)index);
1609  markCacheValueRealized(subsys, cx);
1610  }
1611 
1612  // You can update at any time a variable that was allocated during
1613  // realizeTopology(), but later variables must wait until you have done
1614  // realizeModel(). This always backs the stage up to one earlier than the
1615  // variable's "invalidates" stage, and if there is an auto-update cache
1616  // entry it is also invalidated, regardless of its "depends on" stage.
1617  AbstractValue&
1618  updDiscreteVariable(SubsystemIndex subsys, DiscreteVariableIndex index) {
1619  PerSubsystemInfo& ss = subsystems[subsys];
1620 
1621  SimTK_INDEXCHECK(index,(int)ss.discreteInfo.size(),
1622  "StateImpl::updDiscreteVariable()");
1623  DiscreteVarInfo& dv = ss.discreteInfo[index];
1624 
1625  if (dv.getAllocationStage() > Stage::Topology) {
1626  SimTK_STAGECHECK_GE(getSubsystemStage(subsys),
1627  Stage::Model, "StateImpl::updDiscreteVariable()");
1628  }
1629 
1630  invalidateAll(dv.getInvalidatedStage());
1631 
1632  // Invalidate the auto-update entry, if any.
1633  const CacheEntryIndex cx = dv.getAutoUpdateEntry();
1634  if (cx.isValid()) {
1635  CacheEntryInfo& ce = ss.cacheInfo[cx];
1636  ce.invalidate();
1637  }
1638 
1639  // We're now marking this variable as having been updated at the
1640  // current time.
1641  return dv.updValue(t);
1642  }
1643 
1644  Stage getCacheEntryAllocationStage
1645  (SubsystemIndex subsys, CacheEntryIndex index) const {
1646  const PerSubsystemInfo& ss = subsystems[subsys];
1647  SimTK_INDEXCHECK(index,(int)ss.cacheInfo.size(),
1648  "StateImpl::getCacheEntryAllocationStage()");
1649  const CacheEntryInfo& ce = ss.cacheInfo[index];
1650  return ce.getAllocationStage();
1651  }
1652 
1653  // Stage >= ce.stage
1654  // This method gets called a lot, so make it fast in Release mode.
1655  const AbstractValue&
1656  getCacheEntry(SubsystemIndex subsys, CacheEntryIndex index) const {
1657  const PerSubsystemInfo& ss = subsystems[subsys];
1658 
1659  SimTK_INDEXCHECK(index,(int)ss.cacheInfo.size(),
1660  "StateImpl::getCacheEntry()");
1661  const CacheEntryInfo& ce = ss.cacheInfo[index];
1662 
1663  // These two unconditional checks are somewhat expensive; I'm leaving
1664  // them in though because they catch so many user errors.
1665  // (sherm 20130222).
1666  SimTK_STAGECHECK_GE_ALWAYS(ss.currentStage,
1667  ce.getDependsOnStage(), "StateImpl::getCacheEntry()");
1668 
1669  if (ss.currentStage < ce.getComputedByStage()) {
1670  const StageVersion currentDependsOnVersion =
1671  ss.stageVersions[ce.getDependsOnStage()];
1672  const StageVersion lastCacheVersion =
1673  ce.getVersionWhenLastComputed();
1674 
1675  if (lastCacheVersion != currentDependsOnVersion) {
1676  SimTK_THROW4(Exception::CacheEntryOutOfDate,
1677  ss.currentStage, ce.getDependsOnStage(),
1678  currentDependsOnVersion, lastCacheVersion);
1679  }
1680  }
1681 
1682  // If we get here then we're either past the "computed by" stage, or
1683  // we're past "depends on" with an explicit validation having been made
1684  // at the "depends on" stage's current version.
1685 
1686  return ce.getValue();
1687  }
1688 
1689  // You can access a cache entry for update any time after it has been
1690  // allocated. This does not affect the stage.
1691  AbstractValue&
1692  updCacheEntry(SubsystemIndex subsys, CacheEntryIndex index) const {
1693  const PerSubsystemInfo& ss = subsystems[subsys];
1694 
1695  SimTK_INDEXCHECK(index,(int)ss.cacheInfo.size(),
1696  "StateImpl::updCacheEntry()");
1697  CacheEntryInfo& ce = ss.cacheInfo[index];
1698 
1699  return ce.updValue();
1700  }
1701 
1702  bool isCacheValueRealized(SubsystemIndex subx, CacheEntryIndex cx) const {
1703  const PerSubsystemInfo& ss = subsystems[subx];
1704  SimTK_INDEXCHECK(cx,(int)ss.cacheInfo.size(),
1705  "StateImpl::isCacheValueRealized()");
1706  const CacheEntryInfo& ce = ss.cacheInfo[cx];
1707  return ce.isCurrent(getSubsystemStage(subx),
1708  getSubsystemStageVersions(subx));
1709  }
1710  void markCacheValueRealized(SubsystemIndex subx, CacheEntryIndex cx) const {
1711  const PerSubsystemInfo& ss = subsystems[subx];
1712  SimTK_INDEXCHECK(cx,(int)ss.cacheInfo.size(),
1713  "StateImpl::markCacheValueRealized()");
1714  CacheEntryInfo& ce = ss.cacheInfo[cx];
1715 
1716  // If this cache entry depends on anything, it can't be valid unless
1717  // we're at least *working* on its depends-on stage, meaning the current
1718  // stage would have to be the one before that. The depends-on stage is
1719  // required to be at least Stage::Topology, so its prev() stage exists.
1720  SimTK_STAGECHECK_GE(getSubsystemStage(subx),
1721  ce.getDependsOnStage().prev(),
1722  "StateImpl::markCacheValueRealized()");
1723 
1724  ce.markAsComputed(getSubsystemStageVersions(subx));
1725  }
1726 
1727  void markCacheValueNotRealized
1728  (SubsystemIndex subx, CacheEntryIndex cx) const {
1729  const PerSubsystemInfo& ss = subsystems[subx];
1730  SimTK_INDEXCHECK(cx,(int)ss.cacheInfo.size(),
1731  "StateImpl::markCacheValueNotRealized()");
1732  CacheEntryInfo& ce = ss.cacheInfo[cx];
1733 
1734  ce.invalidate();
1735  }
1736 
1737  StageVersion getSystemTopologyStageVersion() const
1738  { return systemStageVersions[Stage::Topology]; }
1739 
1740  void setSystemTopologyStageVersion(StageVersion topoVersion)
1741  { assert(topoVersion>0);
1742  systemStageVersions[Stage::Topology]=topoVersion; }
1743 
1744  // Capture the stage versions only for currently-realized stages.
1745  void getSystemStageVersions(Array_<StageVersion>& versions) const {
1746  versions.resize(currentSystemStage+1);
1747  for (int i=0; i <= currentSystemStage; ++i)
1748  versions[i] = systemStageVersions[i];
1749  }
1750 
1751  // If the current state is realized at least as high as the previous one,
1752  // then report Stage::Infinity if all of those stage versions match.
1753  // Otherwise report either the first mismatch or the first now-invalid
1754  // stage if lower stages match.
1755  Stage getLowestSystemStageDifference
1756  (const Array_<StageVersion>& prevVersions) const {
1757  const int nRealizedBefore = (int)prevVersions.size();
1758  const int nRealizedNow = (int)currentSystemStage+1; // count from 0
1759  const int nRealizedBoth = std::min(nRealizedBefore,nRealizedNow);
1760 
1761  // First check the stages both had in common.
1762  Stage g=Stage::Topology;
1763  for (; g < nRealizedBoth; ++g)
1764  if (systemStageVersions[g] != prevVersions[g])
1765  return g;
1766 
1767  // All stages that were valid before and now have identical versions.
1768  // If that's all there was before then nothing has changed.
1769  return nRealizedNow >= nRealizedBefore ? Stage::Infinity
1770  : g; // 1st unrealized stage
1771  }
1772 
1773  void autoUpdateDiscreteVariables();
1774 
1775  String toString() const;
1776  String cacheToString() const;
1777 
1778 private:
1779  void initializeStageVersions() {
1780  for (int i=0; i < Stage::NValid; ++i)
1781  systemStageVersions[i] = 1; // never 0
1782  }
1783 
1784 private:
1785  // Shared global resource State variables //
1786 
1787  // We consider time t to be a state variable allocated at Topology stage,
1788  // with its "invalidated" stage Stage::Time. The value of t is NaN in an
1789  // Empty State, and is initialized to zero when the System stage advances
1790  // to Stage::Topology (i.e., when the System is realized to stage Topology).
1791  Real t;
1792 
1793  // The continuous state variables are allocated at Model stage, and given
1794  // their specified initial values when the System stage advances to
1795  // Stage::Model (i.e., when the System is realized to Model stage).
1796  Vector y; // All the continuous state variables together {q,u,z}
1797 
1798  // These are views into y.
1799  Vector q; // Stage::Position continuous variables
1800  Vector u; // Stage::Velocity continuous variables
1801  Vector z; // Stage::Dynamics continuous variables
1802 
1803  // These are not views; there are no qWeights.
1804  Vector uWeights; // scaling for u
1805  Vector zWeights; // scaling for z
1806 
1807  // These are Instance stage state variables.
1808  Vector qerrWeights; // Scaling for perrs
1809  Vector uerrWeights; // Scaling for pdoterrs and verrs
1810 
1811  // Shared global resource Cache entries //
1812 
1813  // This is the System's currently highest-valid Stage.
1814  mutable Stage currentSystemStage;
1815  // This contains a counter for each system stage which is bumped each
1816  // time that stage is invalidated. This allows detection of a state
1817  // that has been changed even after a subsequent realization. The
1818  // Topology stage entry should match the System's Topology version.
1819  mutable StageVersion systemStageVersions[Stage::NValid];
1820 
1821  // DIFFERENTIAL EQUATIONS
1822 
1823  // All the state derivatives taken together (qdot,udot,zdot)
1824  mutable Vector ydot;
1825 
1826  // These are views into ydot.
1827  mutable Vector qdot; // Stage::Velocity
1828  mutable Vector udot; // Stage::Acceleration
1829  mutable Vector zdot; // Stage::Acceleration
1830 
1831  // This is an independent cache entry.
1832  mutable Vector qdotdot; // Stage::Acceleration
1833 
1834  // ALGEBRAIC EQUATIONS
1835 
1836  mutable Vector yerr; // All constraint errors together (qerr,uerr)
1837  mutable Vector udoterr; // Stage::Acceleration (Index 1 constraints)
1838  mutable Vector multipliers; // Stage::Acceleration (Index 1 algebraic vars)
1839 
1840  // These are views into yerr.
1841  mutable Vector qerr; // Stage::Position (Index 3 constraints)
1842  mutable Vector uerr; // Stage::Velocity (Index 2 constraints)
1843 
1844  // DISCRETE EQUATIONS
1845 
1846  // All the event triggers together, ordered by stage.
1847  mutable Vector allTriggers;
1848 
1849  // These are views into allTriggers.
1850  mutable Vector triggers[Stage::NValid];
1851 
1852 
1853  // Subsystem support //
1854 
1855  // Subsystem 0 (always present) is for the System as a whole. Its name
1856  // and version are the System name and version.
1857  Array_<PerSubsystemInfo> subsystems;
1858 
1859  // Return true only if all subsystems are realized to at least Stage g.
1860  bool allSubsystemsAtLeastAtStage(Stage g) const {
1861  for (SubsystemIndex i(0); i < (int)subsystems.size(); ++i)
1862  if (subsystems[i].currentStage < g)
1863  return false;
1864  return true;
1865  }
1866 
1867 };
1868 
1869 
1870 //==============================================================================
1871 // INLINE IMPLEMENTATIONS OF STATE METHODS
1872 //==============================================================================
1873 // These mostly just forward to the StateImpl object.
1874 
1875 inline void State::setNumSubsystems(int i) {
1876  updImpl().setNumSubsystems(i);
1877 }
1878 inline void State::initializeSubsystem
1879  (SubsystemIndex subsys, const String& name, const String& version) {
1880  updImpl().initializeSubsystem(subsys, name, version);
1881 }
1882 
1883 inline SubsystemIndex State::addSubsystem
1884  (const String& name, const String& version) {
1885  return updImpl().addSubsystem(name, version);
1886 }
1887 inline int State::getNumSubsystems() const {
1888  return getImpl().getNumSubsystems();
1889 }
1890 inline const String& State::getSubsystemName(SubsystemIndex subsys) const {
1891  return getImpl().getSubsystemName(subsys);
1892 }
1893 inline const String& State::getSubsystemVersion(SubsystemIndex subsys) const {
1894  return getImpl().getSubsystemVersion(subsys);
1895 }
1896 inline const Stage& State::getSubsystemStage(SubsystemIndex subsys) const {
1897  return getImpl().getSubsystemStage(subsys);
1898 }
1899 inline const Stage& State::getSystemStage() const {
1900  return getImpl().getSystemStage();
1901 }
1902 inline void State::invalidateAll(Stage stage) {
1903  updImpl().invalidateAll(stage);
1904 }
1905 inline void State::invalidateAllCacheAtOrAbove(Stage stage) const {
1906  getImpl().invalidateAllCacheAtOrAbove(stage);
1907 }
1908 inline void State::advanceSubsystemToStage(SubsystemIndex subsys, Stage stage) const {
1909  getImpl().advanceSubsystemToStage(subsys, stage);
1910 }
1911 inline void State::advanceSystemToStage(Stage stage) const {
1912  getImpl().advanceSystemToStage(stage);
1913 }
1914 
1916 { return getImpl().getSystemTopologyStageVersion(); }
1917 
1918 // Continuous state variables
1919 inline QIndex State::allocateQ(SubsystemIndex subsys, const Vector& qInit) {
1920  return updImpl().allocateQ(subsys, qInit);
1921 }
1922 inline UIndex State::allocateU(SubsystemIndex subsys, const Vector& uInit) {
1923  return updImpl().allocateU(subsys, uInit);
1924 }
1925 inline ZIndex State::allocateZ(SubsystemIndex subsys, const Vector& zInit) {
1926  return updImpl().allocateZ(subsys, zInit);
1927 }
1928 
1929 // Constraint errors and multipliers
1930 inline QErrIndex State::allocateQErr(SubsystemIndex subsys, int nqerr) const {
1931  return getImpl().allocateQErr(subsys, nqerr);
1932 }
1933 inline UErrIndex State::allocateUErr(SubsystemIndex subsys, int nuerr) const {
1934  return getImpl().allocateUErr(subsys, nuerr);
1935 }
1936 inline UDotErrIndex State::
1937 allocateUDotErr(SubsystemIndex subsys, int nudoterr) const {
1938  return getImpl().allocateUDotErr(subsys, nudoterr);
1939 }
1940 
1941 // Event witness functions
1942 inline EventTriggerByStageIndex State::
1943 allocateEventTrigger(SubsystemIndex subsys, Stage stage, int nevent) const {
1944  return getImpl().allocateEventTrigger(subsys, stage, nevent);
1945 }
1946 
1947 // Discrete Variables
1948 inline DiscreteVariableIndex State::
1949 allocateDiscreteVariable(SubsystemIndex subsys, Stage stage, AbstractValue* v) {
1950  return updImpl().allocateDiscreteVariable(subsys, stage, v);
1951 }
1952 inline DiscreteVariableIndex State::
1954  (SubsystemIndex subsys, Stage invalidates, AbstractValue* v,
1955  Stage updateDependsOn) {
1956  return updImpl().allocateAutoUpdateDiscreteVariable
1957  (subsys, invalidates, v, updateDependsOn);
1958 }
1959 
1960 inline CacheEntryIndex State::
1962  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1963  return getImpl().getDiscreteVarUpdateIndex(subsys, index);
1964 }
1965 inline Stage State::
1967  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1968  return getImpl().getDiscreteVarAllocationStage(subsys, index);
1969 }
1970 inline Stage State::
1972  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1973  return getImpl().getDiscreteVarInvalidatesStage(subsys, index);
1974 }
1975 
1976 inline const AbstractValue& State::
1977 getDiscreteVariable(SubsystemIndex subsys, DiscreteVariableIndex index) const {
1978  return getImpl().getDiscreteVariable(subsys, index);
1979 }
1980 inline Real State::
1982  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1983  return getImpl().getDiscreteVarLastUpdateTime(subsys, index);
1984 }
1985 inline const AbstractValue& State::
1987  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1988  return getImpl().getDiscreteVarUpdateValue(subsys, index);
1989 }
1990 inline AbstractValue& State::
1992  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1993  return getImpl().updDiscreteVarUpdateValue(subsys, index);
1994 }
1995 inline bool State::
1997  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
1998  return getImpl().isDiscreteVarUpdateValueRealized(subsys, index);
1999 }
2000 inline void State::
2002  (SubsystemIndex subsys, DiscreteVariableIndex index) const {
2003  getImpl().markDiscreteVarUpdateValueRealized(subsys, index);
2004 }
2005 
2006 inline AbstractValue& State::
2008  (SubsystemIndex subsys, DiscreteVariableIndex index) {
2009  return updImpl().updDiscreteVariable(subsys, index);
2010 }
2011 inline void State::
2013  (SubsystemIndex i, DiscreteVariableIndex index, const AbstractValue& v) {
2014  updDiscreteVariable(i,index) = v;
2015 }
2016 
2017 // Cache Entries
2018 inline CacheEntryIndex State::
2019 allocateCacheEntry(SubsystemIndex subsys, Stage dependsOn, Stage computedBy,
2020  AbstractValue* v) const {
2021  return getImpl().allocateCacheEntry(subsys, dependsOn, computedBy, v);
2022 }
2023 
2024 inline Stage State::
2025 getCacheEntryAllocationStage(SubsystemIndex subsys, CacheEntryIndex index) const {
2026  return getImpl().getCacheEntryAllocationStage(subsys, index);
2027 }
2028 inline const AbstractValue& State::
2029 getCacheEntry(SubsystemIndex subsys, CacheEntryIndex index) const {
2030  return getImpl().getCacheEntry(subsys, index);
2031 }
2032 inline AbstractValue& State::
2033 updCacheEntry(SubsystemIndex subsys, CacheEntryIndex index) const {
2034  return getImpl().updCacheEntry(subsys, index);
2035 }
2036 
2037 inline bool State::
2038 isCacheValueRealized(SubsystemIndex subx, CacheEntryIndex cx) const {
2039  return getImpl().isCacheValueRealized(subx, cx);
2040 }
2041 inline void State::
2042 markCacheValueRealized(SubsystemIndex subx, CacheEntryIndex cx) const {
2043  getImpl().markCacheValueRealized(subx, cx);
2044 }
2045 inline void State::
2046 markCacheValueNotRealized(SubsystemIndex subx, CacheEntryIndex cx) const {
2047  getImpl().markCacheValueNotRealized(subx, cx);
2048 }
2049 
2050 // Global Resource Dimensions
2051 
2052 inline int State::getNY() const {
2053  return getImpl().getNY();
2054 }
2055 inline int State::getNQ() const {
2056  return getImpl().getNQ();
2057 }
2058 inline SystemYIndex State::getQStart() const {
2059  return getImpl().getQStart();
2060 }
2061 inline int State::getNU() const {
2062  return getImpl().getNU();
2063 }
2064 inline SystemYIndex State::getUStart() const {
2065  return getImpl().getUStart();
2066 }
2067 inline int State::getNZ() const {
2068  return getImpl().getNZ();
2069 }
2070 inline SystemYIndex State::getZStart() const {
2071  return getImpl().getZStart();
2072 }
2073 inline int State::getNYErr() const {
2074  return getImpl().getNYErr();
2075 }
2076 inline int State::getNQErr() const {
2077  return getImpl().getNQErr();
2078 }
2079 inline SystemYErrIndex State::getQErrStart() const {
2080  return getImpl().getQErrStart();
2081 }
2082 inline int State::getNUErr() const {
2083  return getImpl().getNUErr();
2084 }
2085 inline SystemYErrIndex State::getUErrStart() const {
2086  return getImpl().getUErrStart();
2087 }
2088 inline int State::getNUDotErr() const {
2089  return getImpl().getNUDotErr();
2090 }
2091 inline int State::getNMultipliers() const {
2092  return getNUDotErr();
2093 }
2094 inline int State::getNEventTriggers() const {
2095  return getImpl().getNEventTriggers();
2096 }
2097 inline int State::getNEventTriggersByStage(Stage stage) const {
2098  return getImpl().getNEventTriggersByStage(stage);
2099 }
2100 
2101 
2102 
2103 // Per-Subsystem Dimensions
2104 inline SystemQIndex State::getQStart(SubsystemIndex subsys) const {
2105  return getImpl().getQStart(subsys);
2106 }
2107 inline int State::getNQ(SubsystemIndex subsys) const {
2108  return getImpl().getNQ(subsys);
2109 }
2110 inline SystemUIndex State::getUStart(SubsystemIndex subsys) const {
2111  return getImpl().getUStart(subsys);
2112 }
2113 inline int State::getNU(SubsystemIndex subsys) const {
2114  return getImpl().getNU(subsys);
2115 }
2116 inline SystemZIndex State::getZStart(SubsystemIndex subsys) const {
2117  return getImpl().getZStart(subsys);
2118 }
2119 inline int State::getNZ(SubsystemIndex subsys) const {
2120  return getImpl().getNZ(subsys);
2121 }
2122 inline SystemQErrIndex State::getQErrStart(SubsystemIndex subsys) const {
2123  return getImpl().getQErrStart(subsys);
2124 }
2125 inline int State::getNQErr(SubsystemIndex subsys) const {
2126  return getImpl().getNQErr(subsys);
2127 }
2128 inline SystemUErrIndex State::getUErrStart(SubsystemIndex subsys) const {
2129  return getImpl().getUErrStart(subsys);
2130 }
2131 inline int State::getNUErr(SubsystemIndex subsys) const {
2132  return getImpl().getNUErr(subsys);
2133 }
2134 inline SystemUDotErrIndex State::getUDotErrStart(SubsystemIndex subsys) const {
2135  return getImpl().getUDotErrStart(subsys);
2136 }
2137 inline int State::getNUDotErr(SubsystemIndex subsys) const {
2138  return getImpl().getNUDotErr(subsys);
2139 }
2140 inline SystemMultiplierIndex State::getMultipliersStart(SubsystemIndex subsys) const {
2141  return SystemMultiplierIndex(getUDotErrStart(subsys));
2142 }
2143 inline int State::getNMultipliers(SubsystemIndex subsys) const {
2144  return getNUDotErr(subsys);
2145 }
2146 inline SystemEventTriggerByStageIndex State::
2147 getEventTriggerStartByStage(SubsystemIndex subsys, Stage stage) const {
2148  return getImpl().getEventTriggerStartByStage(subsys, stage);
2149 }
2150 inline int State::
2151 getNEventTriggersByStage(SubsystemIndex subsys, Stage stage) const {
2152  return getImpl().getNEventTriggersByStage(subsys, stage);
2153 }
2154 
2155 
2156 
2157 inline const Vector& State::
2158 getEventTriggersByStage(SubsystemIndex subsys, Stage stage) const {
2159  return getImpl().getEventTriggersByStage(subsys, stage);
2160 }
2161 inline Vector& State::
2162 updEventTriggersByStage(SubsystemIndex subsys, Stage stage) const {
2163  return getImpl().updEventTriggersByStage(subsys, stage);
2164 }
2165 inline const Vector& State::getQ(SubsystemIndex subsys) const {
2166  return getImpl().getQ(subsys);
2167 }
2168 inline const Vector& State::getU(SubsystemIndex subsys) const {
2169  return getImpl().getU(subsys);
2170 }
2171 inline const Vector& State::getZ(SubsystemIndex subsys) const {
2172  return getImpl().getZ(subsys);
2173 }
2174 inline const Vector& State::getUWeights(SubsystemIndex subsys) const {
2175  return getImpl().getUWeights(subsys);
2176 }
2177 inline const Vector& State::getZWeights(SubsystemIndex subsys) const {
2178  return getImpl().getZWeights(subsys);
2179 }
2180 inline Vector& State::updQ(SubsystemIndex subsys) {
2181  return updImpl().updQ(subsys);
2182 }
2183 inline Vector& State::updU(SubsystemIndex subsys) {
2184  return updImpl().updU(subsys);
2185 }
2186 inline Vector& State::updZ(SubsystemIndex subsys) {
2187  return updImpl().updZ(subsys);
2188 }
2189 inline Vector& State::updUWeights(SubsystemIndex subsys) {
2190  return updImpl().updUWeights(subsys);
2191 }
2192 inline Vector& State::updZWeights(SubsystemIndex subsys) {
2193  return updImpl().updZWeights(subsys);
2194 }
2195 inline const Vector& State::getQDot(SubsystemIndex subsys) const {
2196  return getImpl().getQDot(subsys);
2197 }
2198 inline const Vector& State::getUDot(SubsystemIndex subsys) const {
2199  return getImpl().getUDot(subsys);
2200 }
2201 inline const Vector& State::getZDot(SubsystemIndex subsys) const {
2202  return getImpl().getZDot(subsys);
2203 }
2204 inline const Vector& State::getQDotDot(SubsystemIndex subsys) const {
2205  return getImpl().getQDotDot(subsys);
2206 }
2207 inline Vector& State::updQDot(SubsystemIndex subsys) const {
2208  return getImpl().updQDot(subsys);
2209 }
2210 inline Vector& State::updUDot(SubsystemIndex subsys) const {
2211  return getImpl().updUDot(subsys);
2212 }
2213 inline Vector& State::updZDot(SubsystemIndex subsys) const {
2214  return getImpl().updZDot(subsys);
2215 }
2216 inline Vector& State::updQDotDot(SubsystemIndex subsys) const {
2217  return getImpl().updQDotDot(subsys);
2218 }
2219 inline const Vector& State::getQErr(SubsystemIndex subsys) const {
2220  return getImpl().getQErr(subsys);
2221 }
2222 inline const Vector& State::getUErr(SubsystemIndex subsys) const {
2223  return getImpl().getUErr(subsys);
2224 }
2225 inline const Vector& State::getQErrWeights(SubsystemIndex subsys) const {
2226  return getImpl().getQErrWeights(subsys);
2227 }
2228 inline const Vector& State::getUErrWeights(SubsystemIndex subsys) const {
2229  return getImpl().getUErrWeights(subsys);
2230 }
2231 inline const Vector& State::getUDotErr(SubsystemIndex subsys) const {
2232  return getImpl().getUDotErr(subsys);
2233 }
2234 inline const Vector& State::getMultipliers(SubsystemIndex subsys) const {
2235  return getImpl().getMultipliers(subsys);
2236 }
2237 inline Vector& State::updQErr(SubsystemIndex subsys) const {
2238  return getImpl().updQErr(subsys);
2239 }
2240 inline Vector& State::updUErr(SubsystemIndex subsys) const {
2241  return getImpl().updUErr(subsys);
2242 }
2243 inline Vector& State::updQErrWeights(SubsystemIndex subsys) {
2244  return updImpl().updQErrWeights(subsys);
2245 }
2246 inline Vector& State::updUErrWeights(SubsystemIndex subsys) {
2247  return updImpl().updUErrWeights(subsys);
2248 }
2249 inline Vector& State::updUDotErr(SubsystemIndex subsys) const {
2250  return getImpl().updUDotErr(subsys);
2251 }
2252 inline Vector& State::updMultipliers(SubsystemIndex subsys) const {
2253  return getImpl().updMultipliers(subsys);
2254 }
2255 
2256 inline SystemEventTriggerIndex State::
2257 getEventTriggerStartByStage(Stage stage) const {
2258  return getImpl().getEventTriggerStartByStage(stage);
2259 }
2260 
2261 inline const Vector& State::getEventTriggers() const {
2262  return getImpl().getEventTriggers();
2263 }
2264 inline const Vector& State::getEventTriggersByStage(Stage stage) const {
2265  return getImpl().getEventTriggersByStage(stage);
2266 }
2267 
2268 inline Vector& State::updEventTriggers() const {
2269  return getImpl().updEventTriggers();
2270 }
2271 inline Vector& State::updEventTriggersByStage(Stage stage) const {
2272  return getImpl().updEventTriggersByStage(stage);
2273 }
2274 
2275 inline const Real& State::getTime() const {
2276  return getImpl().getTime();
2277 }
2278 inline const Vector& State::getY() const {
2279  return getImpl().getY();
2280 }
2281 inline const Vector& State::getQ() const {
2282  return getImpl().getQ();
2283 }
2284 inline const Vector& State::getU() const {
2285  return getImpl().getU();
2286 }
2287 inline const Vector& State::getZ() const {
2288  return getImpl().getZ();
2289 }
2290 inline const Vector& State::getUWeights() const {
2291  return getImpl().getUWeights();
2292 }
2293 inline const Vector& State::getZWeights() const {
2294  return getImpl().getZWeights();
2295 }
2296 Real& State::updTime() {
2297  return updImpl().updTime();
2298 }
2299 inline Vector& State::updY() {
2300  return updImpl().updY();
2301 }
2302 inline void State::setTime(Real t) {
2303  updTime() = t;
2304 }
2305 inline void State::setY(const Vector& y) {
2306  updY() = y;
2307 }
2308 inline Vector& State::updQ() {
2309  return updImpl().updQ();
2310 }
2311 inline Vector& State::updU() {
2312  return updImpl().updU();
2313 }
2314 inline Vector& State::updZ() {
2315  return updImpl().updZ();
2316 }
2317 inline Vector& State::updUWeights() {
2318  return updImpl().updUWeights();
2319 }
2320 inline Vector& State::updZWeights() {
2321  return updImpl().updZWeights();
2322 }
2323 inline void State::setQ(const Vector& q) {
2324  updQ() = q;
2325 }
2326 inline void State::setU(const Vector& u) {
2327  updU() = u;
2328 }
2329 inline void State::setZ(const Vector& z) {
2330  updZ() = z;
2331 }
2332 inline const Vector& State::getYDot() const {
2333  return getImpl().getYDot();
2334 }
2335 inline const Vector& State::getQDot() const {
2336  return getImpl().getQDot();
2337 }
2338 inline const Vector& State::getZDot() const {
2339  return getImpl().getZDot();
2340 }
2341 inline const Vector& State::getUDot() const {
2342  return getImpl().getUDot();
2343 }
2344 inline const Vector& State::getQDotDot() const {
2345  return getImpl().getQDotDot();
2346 }
2347 inline Vector& State::updYDot() const {
2348  return getImpl().updYDot();
2349 }
2350 inline Vector& State::updQDot() const {
2351  return getImpl().updQDot();
2352 }
2353 inline Vector& State::updZDot() const {
2354  return getImpl().updZDot();
2355 }
2356 inline Vector& State::updUDot() const {
2357  return getImpl().updUDot();
2358 }
2359 inline Vector& State::updQDotDot() const {
2360  return getImpl().updQDotDot();
2361 }
2362 inline const Vector& State::getYErr() const {
2363  return getImpl().getYErr();
2364 }
2365 inline const Vector& State::getQErr() const {
2366  return getImpl().getQErr();
2367 }
2368 inline const Vector& State::getUErr() const {
2369  return getImpl().getUErr();
2370 }
2371 inline const Vector& State::getQErrWeights() const {
2372  return getImpl().getQErrWeights();
2373 }
2374 inline const Vector& State::getUErrWeights() const {
2375  return getImpl().getUErrWeights();
2376 }
2377 inline const Vector& State::getUDotErr() const {
2378  return getImpl().getUDotErr();
2379 }
2380 inline const Vector& State::getMultipliers() const {
2381  return getImpl().getMultipliers();
2382 }
2383 inline Vector& State::updYErr() const {
2384  return getImpl().updYErr();
2385 }
2386 inline Vector& State::updQErr() const {
2387  return getImpl().updQErr();
2388 }
2389 inline Vector& State::updUErr() const {
2390  return getImpl().updUErr();
2391 }
2392 inline Vector& State::updQErrWeights() {
2393  return updImpl().updQErrWeights();
2394 }
2395 inline Vector& State::updUErrWeights() {
2396  return updImpl().updUErrWeights();
2397 }
2398 inline Vector& State::updUDotErr() const {
2399  return getImpl().updUDotErr();
2400 }
2401 inline Vector& State::updMultipliers() const {
2402  return getImpl().updMultipliers();
2403 }
2404 
2405 inline void State::
2407 { return updImpl().setSystemTopologyStageVersion(topoVersion); }
2408 
2409 inline void State::
2410 getSystemStageVersions(Array_<StageVersion>& versions) const {
2411  return getImpl().getSystemStageVersions(versions);
2412 }
2413 inline Stage State::
2414 getLowestSystemStageDifference(const Array_<StageVersion>& prev) const {
2415  return getImpl().getLowestSystemStageDifference(prev);
2416 }
2417 inline void State::autoUpdateDiscreteVariables() {
2418  updImpl().autoUpdateDiscreteVariables();
2419 }
2420 
2421 inline String State::toString() const {
2422  return getImpl().toString();
2423 }
2424 inline String State::cacheToString() const {
2425  return getImpl().cacheToString();
2426 }
2427 
2428 
2429 } // namespace SimTK
2430  // End of hiding from Doxygen
2432 
2433 #endif // SimTK_SimTKCOMMON_STATE_IMPL_H_
2434 
2435 
AbstractValue & updDiscreteVarUpdateValue(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return a writable reference to the value of its associated up...
Vector & updUErrWeights()
Set the unit weighting (1/unit error) for each of the mp+mv velocity-level inline constraints...
void getSystemStageVersions(Array_< StageVersion > &versions) const
(Advanced) Record the current version numbers of each valid System-level stage.
const Vector & getUDot() const
SystemYErrIndex getUErrStart() const
Returns the yErr index at which the uErr's begin. Callable at Instance stage.
const String & getSubsystemVersion(SubsystemIndex) const
Stage getCacheEntryAllocationStage(SubsystemIndex, CacheEntryIndex) const
At what stage was this State when this cache entry was allocated? The answer must be Stage::Empty...
Definition: Stage.h:72
Physical parameters set.
Definition: Stage.h:56
int getNYErr() const
Get the total number nyerr=nqerr+nuerr of shared cache entries for position-level and velocity-level ...
void setZ(const Vector &z)
String toString() const
Vector & updQDot() const
Vector & updQErrWeights()
Set the unit weighting (1/unit error) for each of the mp+mquat position inline constraint equations...
bool isDiscreteVarUpdateValueRealized(SubsystemIndex, DiscreteVariableIndex) const
Check whether the update value for this auto-update discrete variable has already been computed since...
#define SimTK_STAGECHECK_LT_ALWAYS(currentStage, targetStage, methodNm)
Definition: ExceptionMacros.h:183
Modeling choices made.
Definition: Stage.h:55
void setTime(Real t)
An alternate syntax equivalent to updTime() and updY().
const Stage & getSubsystemStage(SubsystemIndex) const
int getNU() const
Get total number of shared u's (generalized speeds; mobilities).
AbstractValue & updCacheEntry(SubsystemIndex, CacheEntryIndex) const
Retrieve a writable reference to the value contained in a particular cache entry. ...
void markCacheValueNotRealized(SubsystemIndex, CacheEntryIndex) const
Normally cache entries are invalidated automatically, however this method allows manual invalidation ...
Definition: Stage.h:68
void advanceSubsystemToStage(SubsystemIndex, Stage) const
Advance a particular Subsystem's current stage by one to the indicated stage.
QErrIndex allocateQErr(SubsystemIndex, int nqerr) const
Allocate nqerr cache slots to hold the current error for position-level (holonomic) constraint equati...
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
#define SimTK_STAGECHECK_GE_ALWAYS(currentStage, targetStage, methodNm)
Definition: ExceptionMacros.h:180
CacheEntryIndex allocateCacheEntry(SubsystemIndex, Stage earliest, Stage latest, AbstractValue *) const
There are two Stages supplied explicitly as arguments to this method: earliest and latest...
const Stage & getSystemStage() const
This returns the *global* stage for this State.
const Vector & getYErr() const
Return the current constraint errors for all constraints.
Spatial velocities available.
Definition: Stage.h:59
const Vector & getQErrWeights() const
Get the unit weighting (1/unit error) for each of the mp+mquat position inline constraints equations...
Lower than any legitimate Stage.
Definition: Stage.h:53
Real getDiscreteVarLastUpdateTime(SubsystemIndex, DiscreteVariableIndex) const
Return the time of last update for this discrete variable.
int size() const
Definition: VectorBase.h:396
Vector & updYErr() const
These are mutable.
void setY(const Vector &y)
SystemEventTriggerIndex getEventTriggerStartByStage(Stage) const
Return the index within the global event trigger array at which the first of the event triggers assoc...
int getNQErr() const
Return the total number nqerr=mp+nQuaternions of cache entries for position-level constraint errors...
const AbstractValue & getDiscreteVariable(SubsystemIndex, DiscreteVariableIndex) const
Get the current value of the indicated discrete variable.
ELEM min(const VectorBase< ELEM > &v)
Definition: VectorMath.h:178
UDotErrIndex allocateUDotErr(SubsystemIndex, int nudoterr) const
Allocate nudoterr cache slots to hold the current error for acceleration-level (acceleration-only, nonholonomic first derivative, and holonomic second derivative) constraint equations.
SystemYIndex getUStart() const
Returns the y index at which the u's begin. Callable at Model stage.
Vector & updZDot() const
const Vector & getUErr() const
CacheEntryIndex getDiscreteVarUpdateIndex(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return the CacheEntryIndex for its associated update cache en...
SystemUDotErrIndex getUDotErrStart(SubsystemIndex) const
Vector & updY()
void autoUpdateDiscreteVariables()
(Advanced) This is called at the beginning of every integration step to set the values of auto-update...
Vector & updUDotErr() const
bool isCacheValueRealized(SubsystemIndex, CacheEntryIndex) const
Check whether the value in a particular cache entry has been recalculated since the last change to th...
int getNMultipliers() const
Return the total number of constraint multipliers; necessarily the same as the number of acceleration...
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:577
int getNUErr() const
Return the total number nuerr=mp+mv of cache entries for velocity-level constraint errors (including ...
Vector & updQ()
These are just views into Y.
int getNQ() const
Get total number of shared q's (generalized coordinates; second order state variables).
const Real NaN
This is the IEEE "not a number" constant for this implementation of the default-precision Real type; ...
#define SimTK_STAGECHECK_RANGE_ALWAYS(lower, current, upper, methodNm)
Definition: ExceptionMacros.h:186
void setDiscreteVariable(SubsystemIndex, DiscreteVariableIndex, const AbstractValue &)
Alternate interface to updDiscreteVariable.
AbstractValue & updDiscreteVariable(SubsystemIndex, DiscreteVariableIndex)
Get a writable reference to the value stored in the indicated discrete state variable dv...
void setU(const Vector &u)
int getNumSubsystems() const
Return the number of Subsystems known to this State.
DiscreteVariableIndex allocateAutoUpdateDiscreteVariable(SubsystemIndex, Stage invalidates, AbstractValue *, Stage updateDependsOn)
This method allocates a DiscreteVariable whose value should be updated automatically after each time ...
const Vector & getEventTriggers() const
const Vector & getQDotDot() const
This has its own space, not a view.
Vector & updQDotDot() const
This is a separate shared cache entry, not part of YDot.
Report-only quantities evaluated.
Definition: Stage.h:62
void setSystemTopologyStageVersion(StageVersion topoVersion)
(Advanced) This explicitly modifies the Topology stage version; don't use this method unless you know...
SubsystemIndex addSubsystem(const String &name, const String &version)
Register a new subsystem as a client of this State.
const Vector & getZWeights() const
Get a unit weighting (1/unit change) for each z that can be used to weight a vector dz so that the di...
System topology realized.
Definition: Stage.h:54
Forces calculated.
Definition: Stage.h:60
Stage getLowestSystemStageDifference(const Array_< StageVersion > &prevVersions) const
(Advanced) Given a list of per-stage version numbers extracted by an earlier call to getSystemStageVe...
Vector & updYDot() const
These are mutable.
Spatial configuration available.
Definition: Stage.h:58
Stage getDiscreteVarAllocationStage(SubsystemIndex, DiscreteVariableIndex) const
At what stage was this State when this discrete variable was allocated? The answer must be Stage::Emp...
const Vector & getZ() const
Real & updTime()
You can call these as long as System stage >= Model, but the stage will be backed up if necessary to ...
Vector & updQErr() const
Vector & updU()
SystemYIndex getQStart() const
Returns the y index at which the q's begin. Callable at Model stage.
DiscreteVariableIndex allocateDiscreteVariable(SubsystemIndex, Stage invalidates, AbstractValue *)
The Stage supplied here in the call is the earliest subsystem stage which is invalidated by a change ...
const Vector & getUErrWeights() const
Get the unit weighting (1/unit error) for each of the mp+mv velocity-level inline constraint equation...
const Vector & getUDotErr() const
These have their own space, they are not views.
Vector & updUDot() const
const Vector & getQDot() const
These are just views into YDot.
Higher than any legitimate Stage.
Definition: Stage.h:63
const Vector & getU() const
const Vector & getQ() const
These are just views into Y.
void setQ(const Vector &q)
Alternate interface.
const Vector & getEventTriggersByStage(Stage) const
#define SimTK_ERRCHK2(cond, whereChecked, fmt, a1, a2)
Definition: ExceptionMacros.h:328
int getNUDotErr() const
Return the total number nudotErr=mp+mv+ma of cache entries for acceleration-level constraint errors (...
const AbstractValue & getCacheEntry(SubsystemIndex, CacheEntryIndex) const
Retrieve a const reference to the value contained in a particular cache entry.
UErrIndex allocateUErr(SubsystemIndex, int nuerr) const
Allocate nuerr cache slots to hold the current error for velocity-level (nonholonomic and holonomic f...
SystemYIndex getZStart() const
Returns the y index at which the z's begin. Callable at Model stage.
const Vector & getQErr() const
These are just views into YErr.
void setNumSubsystems(int i)
Set the number of subsystems in this state.
int getNEventTriggers() const
Return the total number of event trigger function slots in the cache.
Vector & updUErr() const
Vector_< Real > Vector
Variable-size column vector of Real elements; abbreviation for Vector_.
Definition: BigMatrix.h:1473
StageVersion getSystemTopologyStageVersion() const
The Topology stage version number (an integer) stored in this State must match the topology cache ver...
#define SimTK_INDEXCHECK(ix, ub, where)
Definition: ExceptionMacros.h:145
QIndex allocateQ(SubsystemIndex, const Vector &qInit)
Allocate generalized coordinates q, which are second order continuous state variables.
const AbstractValue & getDiscreteVarUpdateValue(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return the current value of its associated update cache entry...
SystemMultiplierIndex getMultipliersStart(SubsystemIndex) const
const Vector & getYDot() const
Vector & updUWeights()
Set u weights (and q weights indirectly).
UIndex allocateU(SubsystemIndex, const Vector &uInit)
Allocate generalized speeds u, which are first order continuous state variables related to the deriva...
int getNY() const
Get the total number ny=nq+nu+nz of shared continuous state variables.
void initializeSubsystem(SubsystemIndex, const String &name, const String &version)
Set the name and version for a given subsystem, which must already have a slot allocated.
Vector & updZWeights()
Set z weights.
void advanceSystemToStage(Stage) const
Advance the System-level current stage by one to the indicated stage.
For iterating over meaningful stage values.
Definition: Stage.h:67
const Vector & getMultipliers() const
ZIndex allocateZ(SubsystemIndex, const Vector &zInit)
Allocate auxiliary first order continuous state variables z.
const Real & getTime() const
You can call these as long as *system* stage >= Model.
const String & getSubsystemName(SubsystemIndex) const
Vector & updZ()
const Vector & getZDot() const
const Vector & getY() const
A new time has been realized.
Definition: Stage.h:57
Stage getDiscreteVarInvalidatesStage(SubsystemIndex, DiscreteVariableIndex) const
What is the earliest stage that is invalidated when this discrete variable is modified? All later stages are also invalidated.
const Vector & getUWeights() const
Get a unit weighting (1/unit change) for each u that can be used to weight a vector du so that the di...
String cacheToString() const
Vector & updEventTriggers() const
void markDiscreteVarUpdateValueRealized(SubsystemIndex, DiscreteVariableIndex) const
Mark the update value for this auto-update discrete variable as up-to-date with respect to the state ...
Accelerations and multipliers calculated.
Definition: Stage.h:61
void invalidateAll(Stage)
If any subsystem or the system stage is currently at or higher than the passed-in one...
#define SimTK_STAGECHECK_GE(currentStage, targetStage, methodNm)
Definition: ExceptionMacros.h:208
SystemYErrIndex getQErrStart() const
Returns the yErr index at which the qErr's begin. Callable at Instance stage.
EventTriggerByStageIndex allocateEventTrigger(SubsystemIndex, Stage stage, int nevent) const
Allocate room for nevent witness function values that will be available at the indicated stage...
#define SimTK_THROW4(exc, a1, a2, a3, a4)
Definition: Exception.h:317
void invalidateAllCacheAtOrAbove(Stage) const
If any subsystem or the system stage is currently at or higher than the passed-in one...
int StageVersion
This is the type to use for Stage version numbers.
Definition: State.h:160
Vector & updEventTriggersByStage(Stage) const
Vector & updMultipliers() const
int getNZ() const
Get total number of shared z's (auxiliary state variables).
int getNEventTriggersByStage(Stage) const
Return the size of the partition of event trigger functions which are evaluated at a given Stage...
void markCacheValueRealized(SubsystemIndex, CacheEntryIndex) const
Mark the value of a particular cache entry as up to date after it has been recalculated.