Simbody  3.7
Stage.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_STAGE_H_
2 #define SimTK_SimTKCOMMON_STAGE_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-15 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
30 
31 #include <cassert>
32 #include <iostream>
33 #include <iomanip>
34 #include <cstdarg>
35 
36 namespace SimTK {
37 
44 typedef long long StageVersion;
45 
52 typedef long long ValueVersion;
53 
66 class Stage {
67 public:
68  enum Level {
69  Empty = 0,
70  Topology = 1,
71  Model = 2,
72  Instance = 3,
73  Time = 4,
74  Position = 5,
75  Velocity = 6,
76  Dynamics = 7,
78  Report = 9,
79  Infinity = 10,
80 
85  };
86 
87  enum {
90  };
91 
93  Stage() : level(Stage::Empty) {}
95  Stage(Level l) {
96  assert(LowestValid <= l && l <= HighestValid);
97  level = l;
98  }
100  explicit Stage(int l) {
101  assert(LowestValid <= l && l <= HighestValid);
102  level = Level(l);
103  }
105  operator int() const {return level;}
106 
107  bool operator==(Level other) const {return level==other;}
108  bool operator!=(Level other) const {return level!=other;}
109  bool operator<(Level other) const {return level<other;}
110  bool operator<=(Level other) const {return level<=other;}
111  bool operator>(Level other) const {return level>other;}
112  bool operator>=(Level other) const {return level>=other;}
113  bool operator==(Stage other) const {return level==other.level;}
114  bool operator!=(Stage other) const {return level!=other.level;}
115  bool operator<(Stage other) const {return level<other.level;}
116  bool operator<=(Stage other) const {return level<=other.level;}
117  bool operator>(Stage other) const {return level>other.level;}
118  bool operator>=(Stage other) const {return level>=other.level;}
119 
120  // Prefix operators
121  const Stage& operator++()
122  { assert(level<HighestValid); level=Level(level+1); return *this; }
123  const Stage& operator--()
124  { assert(level>LowestValid); level=Level(level-1); return *this;}
125  // Postfix operators
127  { assert(level<HighestValid); level=Level(level+1); return prev(); }
129  { assert(level>LowestValid); level=Level(level-1); return next(); }
130 
134  Stage next() const
135  { assert(level<HighestValid); return Stage(Level(level+1)); }
139  Stage prev() const
140  { assert(level>LowestValid); return Stage(Level(level-1)); }
141 
144  String getName() const {
145  switch (level) {
146  case Empty: return "Empty"; break;
147  case Topology: return "Topology"; break;
148  case Model: return "Model"; break;
149  case Instance: return "Instance"; break;
150  case Time: return "Time"; break;
151  case Position: return "Position"; break;
152  case Velocity: return "Velocity"; break;
153  case Dynamics: return "Dynamics"; break;
154  case Acceleration: return "Acceleration"; break;
155  case Report: return "Report"; break;
156  case Infinity: return "Infinity"; break;
157  default: assert(!"Stage::getName(): illegal level");
158  }
159  return String("INVALID STAGE LEVEL ") + String(level);
160  }
161 
163  void invalidate(Stage tooHigh) {
164  if (level >= tooHigh.level)
165  *this = tooHigh.prev();
166  }
167 
171  bool isInRuntimeRange() const
172  { return Stage::LowestRuntime <= level
173  && level <= Stage::HighestRuntime; }
174 
175 private:
176  Level level;
177 };
178 
179 
180 
181 
182 namespace Exception {
183 
184 #ifdef _MSC_VER
185 #pragma warning(push)
186 #pragma warning(disable:4996) // don't warn about sprintf, etc.
187 #endif
188 
190 public:
191  RealizeTopologyMustBeCalledFirst(const char* fn, int ln,
192  const char* objectType, // e.g., "System", "Subsystem"
193  const char* objectName, const char* methodName) : Base(fn,ln)
194  {
195  setMessage(String(methodName) + ": " + String(objectType) + " " + String(objectName)
196  + " topology has not been realized since the last topological change"
197  " -- you must call realizeTopology() first.");
198  }
199  virtual ~RealizeTopologyMustBeCalledFirst() throw() { }
200 };
201 
203 public:
205  const char* objectType, // e.g., "System", "Subsystem"
206  const char* objectName, const char* methodName,
207  int sysTopoVersion,
208  int stateTopoVersion) : Base(fn,ln)
209  {
210  setMessage(String(methodName)
211  + ": The given State's Topology stage version number ("
212  + String(stateTopoVersion)
213  + ") doesn't match the current topology cache version number ("
214  + String(sysTopoVersion)
215  + ") of " + String(objectType) + " " + String(objectName) + "."
216  + " That means there has been a topology change to this System since this"
217  " State was created so they are no longer compatible. You should create"
218  " a new State from the System's default State."
219  " (Loopholes exist for advanced users.)");
220  }
222 };
223 
224 
225 
226 class StageTooLow : public Base {
227 public:
228  StageTooLow(const char* fn, int ln,
229  Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
230  {
231  setMessage("Expected stage to be at least " + targetStage.getName() + " in " + String(where)
232  + " but current stage was " + currentStage.getName());
233  }
234  virtual ~StageTooLow() throw() { }
235 };
236 
237 class StageIsWrong : public Base {
238 public:
239  StageIsWrong(const char* fn, int ln,
240  Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
241  {
242  setMessage("Expected stage to be " + targetStage.getName() + " in " + String(where)
243  + " but current stage was " + currentStage.getName());
244  }
245  virtual ~StageIsWrong() throw() { }
246 };
247 
248 class StageTooHigh : public Base {
249 public:
250  StageTooHigh(const char* fn, int ln,
251  Stage currentStage, Stage targetStage, const char* where) : Base(fn,ln)
252  {
253  setMessage("Expected stage to be less than " + targetStage.getName() + " in " + String(where)
254  + " but current stage was " + currentStage.getName());
255  }
256  virtual ~StageTooHigh() throw() { }
257 };
258 
259 class StageOutOfRange : public Base {
260 public:
261  StageOutOfRange(const char* fn, int ln,
262  Stage lower, Stage currentStage, Stage upper, const char* where) : Base(fn,ln)
263  {
264  setMessage("Expected (" + lower.getName() + " <= stage <= " + upper.getName() + ") in " + String(where)
265  + " but stage was " + currentStage.getName());
266  }
267  virtual ~StageOutOfRange() throw() { }
268 };
269 
270 class CacheEntryOutOfDate : public Base {
271 public:
272  CacheEntryOutOfDate(const char* fn, int ln,
273  Stage currentStage, Stage dependsOn,
274  StageVersion dependsOnVersion, StageVersion lastCalculatedVersion)
275  : Base(fn,ln)
276  {
277  setMessage("State Cache entry was out of date at Stage " + currentStage.getName()
278  + ". This entry depends on version " + String(dependsOnVersion)
279  + " of Stage " + dependsOn.getName()
280  + " but was last updated at version " + String(lastCalculatedVersion) + ".");
281  }
282  virtual ~CacheEntryOutOfDate() throw() { }
283 };
284 
285 // An attempt to realize a particular subsystem to a particular stage failed.
286 class RealizeCheckFailed : public Base {
287 public:
288  RealizeCheckFailed(const char* fn, int ln, Stage g,
289  int subsystemId, const char* subsystemName,
290  const char* fmt, ...) : Base(fn,ln)
291  {
292  char buf[1024];
293  va_list args;
294  va_start(args, fmt);
295  vsprintf(buf, fmt, args);
296  setMessage("Couldn't realize subsystem " + String(subsystemId)
297  + "(" + String(subsystemName) + ") to Stage "
298  + g.getName() + ": " + String(buf) + ".");
299  va_end(args);
300  }
301  virtual ~RealizeCheckFailed() throw() { }
302 };
303 
304 #ifdef _MSC_VER
305 #pragma warning(pop)
306 #endif
307 
308 } // namespace Exception
309 
310 inline std::ostream& operator<<(std::ostream& o, Stage g)
311 { o << g.getName(); return o; }
312 
313 
314 } // namespace SimTK
315 
316  // REALIZECHECKs: these should be used to catch and report problems that
317  // occur when realizing a subsystem.
318 
319 #define SimTK_REALIZECHECK_ALWAYS(cond,stage,subsysIx,subsysName,msg) \
320  do{if(!(cond))SimTK_THROW4(SimTK::Exception::RealizeCheckFailed, \
321  (stage),(subsysIx),(subsysName),(msg)); \
322  }while(false)
323 #define SimTK_REALIZECHECK1_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1) \
324  do{if(!(cond))SimTK_THROW5(SimTK::Exception::RealizeCheckFailed, \
325  (stage),(subsysIx),(subsysName),(msg),(a1)); \
326  }while(false)
327 #define SimTK_REALIZECHECK2_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2)\
328  do{if(!(cond))SimTK_THROW6(SimTK::Exception::RealizeCheckFailed, \
329  (stage),(subsysIx),(subsysName),(msg),(a1),(a2)); \
330  }while(false)
331 #define SimTK_REALIZECHECK3_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3) \
332  do{if(!(cond))SimTK_THROW7(SimTK::Exception::RealizeCheckFailed, \
333  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3)); \
334  }while(false)
335 #define SimTK_REALIZECHECK4_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4) \
336  do{if(!(cond))SimTK_THROW8(SimTK::Exception::RealizeCheckFailed, \
337  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4)); \
338  }while(false)
339 #define SimTK_REALIZECHECK5_ALWAYS(cond,stage,subsysIx,subsysName,msg,a1,a2,a3,a4,a5) \
340  do{if(!(cond))SimTK_THROW9(SimTK::Exception::RealizeCheckFailed, \
341  (stage),(subsysIx),(subsysName),(msg),(a1),(a2),(a3),(a4),(a5)); \
342  }while(false)
343 
344 
345 #endif // SimTK_SimTKCOMMON_STAGE_H_
virtual ~RealizeCheckFailed()
Definition: Stage.h:301
Definition: Stage.h:88
Physical parameters set.
Definition: Stage.h:72
bool operator==(Stage other) const
Definition: Stage.h:113
bool operator>(Stage other) const
Definition: Stage.h:117
Definition: Stage.h:259
Modeling choices made.
Definition: Stage.h:71
Stage(Level l)
This is an implicit conversion from Stage::Level to Stage.
Definition: Stage.h:95
Level
Definition: Stage.h:68
RealizeTopologyMustBeCalledFirst(const char *fn, int ln, const char *objectType, const char *objectName, const char *methodName)
Definition: Stage.h:191
virtual ~CacheEntryOutOfDate()
Definition: Stage.h:282
void setMessage(const std::string &msgin)
Definition: Exception.h:57
String getName() const
Return a printable name corresponding to the stage level currently stored in this Stage...
Definition: Stage.h:144
Definition: Stage.h:84
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
bool operator!=(Stage other) const
Definition: Stage.h:114
bool operator<=(Stage other) const
Definition: Stage.h:116
Spatial velocities available.
Definition: Stage.h:75
Lower than any legitimate Stage.
Definition: Stage.h:69
Stage operator--(int)
Definition: Stage.h:128
virtual ~RealizeTopologyMustBeCalledFirst()
Definition: Stage.h:199
bool operator<(Level other) const
Definition: Stage.h:109
This class is basically a glorified enumerated type, type-safe and range checked but permitting conve...
Definition: Stage.h:66
bool operator>=(Level other) const
Definition: Stage.h:112
Definition: Stage.h:248
long long StageVersion
This is the type to use for Stage version numbers that get incremented whenever a state variable chan...
Definition: Stage.h:44
bool operator>=(Stage other) const
Definition: Stage.h:118
CacheEntryOutOfDate(const char *fn, int ln, Stage currentStage, Stage dependsOn, StageVersion dependsOnVersion, StageVersion lastCalculatedVersion)
Definition: Stage.h:272
bool operator>(Level other) const
Definition: Stage.h:111
StageIsWrong(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:239
long long ValueVersion
This is the type to use for state variable version numbers that get incremented whenever a state valu...
Definition: Stage.h:52
void invalidate(Stage tooHigh)
Set this Stage=min(stageNow, tooHigh-1).
Definition: Stage.h:163
bool operator==(Level other) const
Definition: Stage.h:107
virtual ~StageTooHigh()
Definition: Stage.h:256
virtual ~StageIsWrong()
Definition: Stage.h:245
bool operator!=(Level other) const
Definition: Stage.h:108
Report-only quantities evaluated.
Definition: Stage.h:78
System topology realized.
Definition: Stage.h:70
Stage operator++(int)
Definition: Stage.h:126
Forces calculated.
Definition: Stage.h:76
bool isInRuntimeRange() const
Return true if this Stage has one of the meaningful values between Stage::Topology and Stage::Report...
Definition: Stage.h:171
Definition: Exception.h:46
Spatial configuration available.
Definition: Stage.h:74
Definition: Stage.h:89
bool operator<(Stage other) const
Definition: Stage.h:115
Higher than any legitimate Stage.
Definition: Stage.h:79
Stage prev() const
Return the Stage before this one, with Stage::Empty returned if this Stage is already at its lowest v...
Definition: Stage.h:139
For iterating over all stage values.
Definition: Stage.h:81
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition: CompliantContactSubsystem.h:387
Stage()
Default construction gives Stage::Empty.
Definition: Stage.h:93
RealizeCheckFailed(const char *fn, int ln, Stage g, int subsystemId, const char *subsystemName, const char *fmt,...)
Definition: Stage.h:288
const Stage & operator++()
Definition: Stage.h:121
Definition: Stage.h:82
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:62
Stage next() const
Return the Stage following this one, with Stage::Infinity returned if this Stage is already at its hi...
Definition: Stage.h:134
StageOutOfRange(const char *fn, int ln, Stage lower, Stage currentStage, Stage upper, const char *where)
Definition: Stage.h:261
virtual ~StageTooLow()
Definition: Stage.h:234
Mandatory first inclusion for any Simbody source or header file.
Stage(int l)
You can explicitly create a Stage from an int if it is in range.
Definition: Stage.h:100
const Stage & operator--()
Definition: Stage.h:123
StateAndSystemTopologyVersionsMustMatch(const char *fn, int ln, const char *objectType, const char *objectName, const char *methodName, int sysTopoVersion, int stateTopoVersion)
Definition: Stage.h:204
StageTooLow(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:228
virtual ~StageOutOfRange()
Definition: Stage.h:267
For iterating over meaningful stage values.
Definition: Stage.h:83
StageTooHigh(const char *fn, int ln, Stage currentStage, Stage targetStage, const char *where)
Definition: Stage.h:250
A new time has been realized.
Definition: Stage.h:73
Definition: Stage.h:226
bool operator<=(Level other) const
Definition: Stage.h:110
Accelerations and multipliers calculated.
Definition: Stage.h:77
Definition: Stage.h:237
virtual ~StateAndSystemTopologyVersionsMustMatch()
Definition: Stage.h:221