SystemGuts.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SYSTEM_GUTS_H_
00002 #define SimTK_SimTKCOMMON_SYSTEM_GUTS_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-7 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00035 #include "SimTKcommon/basics.h"
00036 #include "SimTKcommon/Simmatrix.h"
00037 #include "SimTKcommon/internal/State.h"
00038 #include "SimTKcommon/internal/System.h"
00039 
00040 namespace SimTK {
00041 
00042 class Subsystem;
00043 class DecorativeGeometry;
00044 
00045 // See below for definitions.
00046 static void systemDestructImplLocator(System::Guts*);
00047 static System::Guts* systemCloneImplLocator(const System::Guts&);
00048 static int systemRealizeTopologyImplLocator(const System::Guts&, State&);
00049 static int systemRealizeModelImplLocator   (const System::Guts&, State&);
00050 static int systemRealizeInstanceImplLocator(const System::Guts&, const State&);
00051 static int systemRealizeTimeImplLocator    (const System::Guts&, const State&);
00052 static int systemRealizePositionImplLocator(const System::Guts&, const State&);
00053 static int systemRealizeVelocityImplLocator(const System::Guts&, const State&);
00054 static int systemRealizeDynamicsImplLocator(const System::Guts&, const State&);
00055 static int systemRealizeAccelerationImplLocator(const System::Guts&, const State&);
00056 static int systemRealizeReportImplLocator      (const System::Guts&, const State&);
00057 static Real systemCalcTimescaleImplLocator(const System::Guts&, const State&);
00058 static int  systemCalcYUnitWeightsImplLocator(const System::Guts&, const State&, Vector& weights);
00059 static int  systemProjectImplLocator(const System::Guts&, State&, Real, const Vector&, const Vector&,
00060                                          Vector&, System::ProjectOptions);
00061 static int  systemCalcYErrUnitTolerancesImplLocator(const System::Guts&, const State&, Vector& ootols);
00062 static int  systemHandleEventsImplLocator(const System::Guts&, State&, System::EventCause, const std::vector<EventId>&,
00063                                               Real, const Vector&, const Vector&, Stage&, bool&);
00064 static int  systemReportEventsImplLocator(const System::Guts&, const State&, System::EventCause, const std::vector<EventId>&);
00065 static int  systemCalcEventTriggerInfoImplLocator(const System::Guts&, const State&, std::vector<System::EventTriggerInfo>&);
00066 static int  systemCalcTimeOfNextScheduledEventImplLocator(const System::Guts&, const State&, Real&, std::vector<EventId>&, bool includeCurrentTime);
00067 static int  systemCalcTimeOfNextScheduledReportImplLocator(const System::Guts&, const State&, Real&, std::vector<EventId>&, bool includeCurrentTime);
00068 
00106 class SimTK_SimTKCOMMON_EXPORT System::Guts {
00107     class GutsRep;
00108     friend class GutsRep;
00109 
00110     // This is the only data member in this class.
00111     GutsRep* rep; // opaque implementation of System::Guts base class.
00112 public:
00113     // Constructor must be inline for binary compatibility. Note that this
00114     // serves as a default constructor since both arguments have defaults.
00115     inline explicit Guts(const String& name="<NONAME>", 
00116                          const String& version="0.0.0");
00117 
00118     // This won't be called directly from library-side code. Instead,
00119     // a method from the explicit virtual function table will be invoked
00120     // which will know where to find this on in the C++ VFT on the client side.
00121     virtual ~Guts() {librarySideDestruction();}
00122 
00123     const String& getName()    const;
00124     const String& getVersion() const;
00125 
00126     void setHasTimeAdvancedEvents(bool hasEm);
00127     bool hasTimeAdvancedEvents() const;
00128 
00130         // EVALUATION (REALIZATION) //
00132 
00133     // These are the routines to which the System class forwards requests.
00134 
00135     const State& getDefaultState() const;
00136     State&       updDefaultState();
00137 
00138     void realize(const State& s, Stage g = Stage::HighestValid) const;
00139 
00140     SubsystemIndex adoptSubsystem(Subsystem& child);
00141 
00142     int getNSubsystems() const;
00143     const Subsystem& getSubsystem(SubsystemIndex)   const;
00144     Subsystem&       updSubsystem(SubsystemIndex);
00145 
00146     // Obtain the owner handle for this System::Guts object.
00147     const System& getSystem() const;
00148     System& updSystem();
00149 
00150     void setOwnerHandle(System&);
00151     bool hasOwnerHandle() const;
00152 
00153     explicit Guts(class GutsRep* r) : rep(r) { }
00154     bool           hasRep() const {return rep!=0;}
00155     const GutsRep& getRep() const {assert(rep); return *rep;}
00156     GutsRep&       updRep() const {assert(rep); return *rep;}
00157 
00158     bool systemTopologyHasBeenRealized() const;
00159     void invalidateSystemTopologyCache() const;
00160 
00161     // Call this routine to invoke the client-side virtual destructor,
00162     // by going through the library-side explicit virtual function table.
00163     static void destruct(System::Guts*);
00164 
00165     // Wrap the cloneImpl virtual method.
00166     System::Guts* clone() const;
00167 
00168     // These routines wrap the virtual realize...Impl() methods to ensure
00169     // good behavior such as checking that stage requirements are met and
00170     // updating the stage at the end. Note that these will do nothing if
00171     // the System stage is already at or greater than the indicated stage.
00172 
00173     const State& realizeTopology() const;
00174     void realizeModel(State&) const;
00175     void realizeInstance    (const State& s) const;
00176     void realizeTime        (const State& s) const;
00177     void realizePosition    (const State& s) const;
00178     void realizeVelocity    (const State& s) const;
00179     void realizeDynamics    (const State& s) const;
00180     void realizeAcceleration(const State& s) const;
00181     void realizeReport      (const State& s) const;
00182 
00183     // These wrap the other virtual methods.
00184     Real calcTimescale(const State&) const;
00185     void calcYUnitWeights(const State&, Vector& weights) const;
00186     void project(State&, Real consAccuracy, const Vector& yweights,
00187                  const Vector& ootols, Vector& yerrest, System::ProjectOptions) const;
00188     void calcYErrUnitTolerances(const State&, Vector& tolerances) const;
00189     void handleEvents
00190        (State&, EventCause, const std::vector<EventId>& eventIds,
00191         Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols,
00192         Stage& lowestModified, bool& shouldTerminate) const;
00193     void reportEvents(const State&, EventCause, const std::vector<EventId>& eventIds) const;
00194     void calcEventTriggerInfo(const State&, std::vector<EventTriggerInfo>&) const;
00195     void calcTimeOfNextScheduledEvent(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00196     void calcTimeOfNextScheduledReport(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00197 
00198     void calcDecorativeGeometryAndAppend(const State&, Stage, 
00199                                          std::vector<DecorativeGeometry>&) const;
00200 
00201 
00202 protected:
00203     Guts(const Guts&);  // copies the base class; for use from derived class copy constructors
00204     
00205     // The destructor is already virtual; see above.
00206 
00207     virtual System::Guts* cloneImpl() const = 0;
00208 
00209     // Override these to change the evaluation order of the Subsystems.
00210     // The default is to evaluate them in increasing order of SubsystemIndex.
00211     // These methods should not be called directly; they are invoked by the
00212     // above wrapper methods. Note: the wrappers *will not* call these
00213     // routines if the system stage has already met the indicated stage level.
00214     // If fact these routines will be called only when the system stage
00215     // is at the level just prior to the one indicated here. For example,
00216     // realizeVelocityImpl() will be called only if the passed-in State
00217     // has been determined to have its system stage exactly Stage::Position.
00218     virtual int realizeTopologyImpl(State&) const;
00219     virtual int realizeModelImpl(State&) const;
00220     virtual int realizeInstanceImpl(const State&) const;
00221     virtual int realizeTimeImpl(const State&) const;
00222     virtual int realizePositionImpl(const State&) const;
00223     virtual int realizeVelocityImpl(const State&) const;
00224     virtual int realizeDynamicsImpl(const State&) const;
00225     virtual int realizeAccelerationImpl(const State&) const;
00226     virtual int realizeReportImpl(const State&) const;
00227 
00228     virtual Real calcTimescaleImpl(const State&) const;
00229 
00230     virtual int calcYUnitWeightsImpl(const State&, Vector& weights) const;
00231 
00232     virtual int projectImpl(State&, Real consAccuracy, const Vector& yweights,
00233                             const Vector& ootols, Vector& yerrest, System::ProjectOptions) const;
00234     virtual int calcYErrUnitTolerancesImpl(const State&, Vector& tolerances) const;
00235 
00236     virtual int handleEventsImpl
00237        (State&, EventCause, const std::vector<EventId>& eventIds,
00238         Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols,
00239         Stage& lowestModified, bool& shouldTerminate) const;
00240 
00241     virtual int reportEventsImpl(const State&, EventCause, const std::vector<EventId>& eventIds) const;
00242 
00243     virtual int calcEventTriggerInfoImpl(const State&, std::vector<EventTriggerInfo>&) const;
00244 
00245     virtual int calcTimeOfNextScheduledEventImpl(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00246     virtual int calcTimeOfNextScheduledReportImpl(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00247 private:
00248     Guts& operator=(const Guts&); // suppress default copy assignment operator
00249 
00250     // These typedefs are used internally to manage the binary-compatible
00251     // handling of the virtual function table.
00252 
00253     // This first entry calls the virtual destructor above to delete the
00254     // heap-allocated object pointed to by the passed-in pointer.
00255     typedef void (*DestructImplLocator)(System::Guts*);
00256     typedef System::Guts* (*CloneImplLocator)(const System::Guts&);
00257 
00258     typedef int (*RealizeWritableStateImplLocator)(const System::Guts&, State&);
00259     typedef int (*RealizeConstStateImplLocator)(const System::Guts&, const State&);
00260     typedef Real (*CalcTimescaleImplLocator)(const System::Guts&, const State&);
00261     typedef int (*CalcUnitWeightsImplLocator)(const System::Guts&, const State&, Vector& weights);
00262 
00263     typedef int (*ProjectImplLocator)(const System::Guts&, State&, Real, const Vector&, const Vector&,
00264                                       Vector&, System::ProjectOptions);
00265 
00266     typedef int (*HandleEventsImplLocator)
00267        (const System::Guts&, State&, EventCause, const std::vector<EventId>&,
00268         Real, const Vector&, const Vector&, Stage&, bool&);
00269     typedef int (*ReportEventsImplLocator)
00270        (const System::Guts&, const State&, EventCause, const std::vector<EventId>&);
00271     typedef int (*CalcEventTriggerInfoImplLocator)
00272        (const System::Guts&, const State&, std::vector<EventTriggerInfo>&);
00273     typedef int (*CalcTimeOfNextScheduledEventImplLocator)
00274        (const System::Guts&, const State&, Real&, std::vector<EventId>&, bool);
00275     typedef int (*CalcTimeOfNextScheduledReportImplLocator)
00276        (const System::Guts&, const State&, Real&, std::vector<EventId>&, bool);
00277 
00278     class EventTriggerInfoRep;
00279 
00280     void librarySideConstruction(const String& name, const String& version);
00281     void librarySideDestruction();
00282 
00283     void registerDestructImpl(DestructImplLocator);
00284     void registerCloneImpl(CloneImplLocator);
00285 
00286     void registerRealizeTopologyImpl    (RealizeWritableStateImplLocator);
00287     void registerRealizeModelImpl       (RealizeWritableStateImplLocator);
00288     void registerRealizeInstanceImpl    (RealizeConstStateImplLocator);
00289     void registerRealizeTimeImpl        (RealizeConstStateImplLocator);
00290     void registerRealizePositionImpl    (RealizeConstStateImplLocator);
00291     void registerRealizeVelocityImpl    (RealizeConstStateImplLocator);
00292     void registerRealizeDynamicsImpl    (RealizeConstStateImplLocator);
00293     void registerRealizeAccelerationImpl(RealizeConstStateImplLocator);
00294     void registerRealizeReportImpl      (RealizeConstStateImplLocator);
00295 
00296     void registerCalcTimescaleImpl(CalcTimescaleImplLocator);
00297     void registerCalcYUnitWeightsImplLocator(CalcUnitWeightsImplLocator);
00298     void registerProjectImpl(ProjectImplLocator);
00299     void registerCalcYErrUnitTolerancesImplLocator(CalcUnitWeightsImplLocator);
00300     void registerHandleEventsImpl(HandleEventsImplLocator);
00301     void registerReportEventsImpl(ReportEventsImplLocator);
00302     void registerCalcEventTriggerInfoImpl(CalcEventTriggerInfoImplLocator);
00303     void registerCalcTimeOfNextScheduledEventImpl(CalcTimeOfNextScheduledEventImplLocator);
00304     void registerCalcTimeOfNextScheduledReportImpl(CalcTimeOfNextScheduledReportImplLocator);
00305 
00306     // We want the locator functions to have access to the protected "Impl"
00307     // virtual methods, so we make them friends.
00308 
00309     friend void systemDestructImplLocator(System::Guts*);
00310     friend System::Guts* systemCloneImplLocator(const System::Guts&);
00311 
00312     friend int systemRealizeTopologyImplLocator(const System::Guts&, State&);
00313     friend int systemRealizeModelImplLocator   (const System::Guts&, State&);
00314     friend int systemRealizeInstanceImplLocator(const System::Guts&, const State&);
00315     friend int systemRealizeTimeImplLocator    (const System::Guts&, const State&);
00316     friend int systemRealizePositionImplLocator(const System::Guts&, const State&);
00317     friend int systemRealizeVelocityImplLocator(const System::Guts&, const State&);
00318     friend int systemRealizeDynamicsImplLocator(const System::Guts&, const State&);
00319     friend int systemRealizeAccelerationImplLocator(const System::Guts&, const State&);
00320     friend int systemRealizeReportImplLocator      (const System::Guts&, const State&);
00321 
00322     friend Real systemCalcTimescaleImplLocator(const System::Guts&, const State&);
00323     friend int  systemCalcYUnitWeightsImplLocator(const System::Guts&, const State&, Vector& weights);
00324     friend int  systemProjectImplLocator(const System::Guts&, State&, Real, const Vector&, const Vector&,
00325                                          Vector&, System::ProjectOptions);
00326     friend int  systemCalcYErrUnitTolerancesImplLocator(const System::Guts&, const State&, Vector& ootols);
00327     friend int  systemHandleEventsImplLocator(const System::Guts&, State&, EventCause, const std::vector<EventId>&,
00328                                               Real, const Vector&, const Vector&, Stage&, bool&);
00329     friend int  systemReportEventsImplLocator(const System::Guts&, const State&, EventCause, const std::vector<EventId>&);
00330     friend int  systemCalcEventTriggerInfoImplLocator(const System::Guts&, const State&, std::vector<EventTriggerInfo>&);
00331     friend int  systemCalcTimeOfNextScheduledEventImplLocator(const System::Guts&, const State&, Real&, std::vector<EventId>&, bool);
00332     friend int  systemCalcTimeOfNextScheduledReportImplLocator(const System::Guts&, const State&, Real&, std::vector<EventId>&, bool);
00333 };
00334 
00335 
00336 // These are used to supply the client-side virtual function to the library, without
00337 // the client and library having to agree on the layout of the virtual function tables.
00338 
00339 static void systemDestructImplLocator(System::Guts* sysp)
00340   { delete sysp; } // invokes virtual destructor
00341 static System::Guts* systemCloneImplLocator(const System::Guts& sys)
00342   { return sys.cloneImpl(); }
00343 
00344 static int systemRealizeTopologyImplLocator(const System::Guts& sys, State& state)
00345   { return sys.realizeTopologyImpl(state); }
00346 static int systemRealizeModelImplLocator(const System::Guts& sys, State& state)
00347   { return sys.realizeModelImpl(state); }
00348 static int systemRealizeInstanceImplLocator(const System::Guts& sys, const State& state)
00349   { return sys.realizeInstanceImpl(state); }
00350 static int systemRealizeTimeImplLocator(const System::Guts& sys, const State& state)
00351   { return sys.realizeTimeImpl(state); }
00352 static int systemRealizePositionImplLocator(const System::Guts& sys, const State& state)
00353   { return sys.realizePositionImpl(state); }
00354 static int systemRealizeVelocityImplLocator(const System::Guts& sys, const State& state)
00355   { return sys.realizeVelocityImpl(state); }
00356 static int systemRealizeDynamicsImplLocator(const System::Guts& sys, const State& state)
00357   { return sys.realizeDynamicsImpl(state); }
00358 static int systemRealizeAccelerationImplLocator(const System::Guts& sys, const State& state)
00359   { return sys.realizeAccelerationImpl(state); }
00360 static int systemRealizeReportImplLocator(const System::Guts& sys, const State& state)
00361   { return sys.realizeReportImpl(state); }
00362 
00363 
00364 static Real systemCalcTimescaleImplLocator(const System::Guts& sys, const State& state)
00365   { return sys.calcTimescaleImpl(state); }
00366 
00367 static int  systemCalcYUnitWeightsImplLocator(const System::Guts& sys, const State& state, Vector& weights)
00368   { return sys.calcYUnitWeightsImpl(state, weights); }
00369 
00370 static int  systemProjectImplLocator
00371    (const System::Guts& sys, State& state, Real consAccuracy,
00372     const Vector& yWeights, const Vector& ooConstraintTols, Vector& yErrest, System::ProjectOptions opts)
00373   { return sys.projectImpl(state, consAccuracy, yWeights, ooConstraintTols, yErrest, opts); }
00374 
00375 static int  systemCalcYErrUnitTolerancesImplLocator(const System::Guts& sys, const State& state, Vector& ootols)
00376   { return sys.calcYErrUnitTolerancesImpl(state, ootols); }
00377 
00378 static int  systemHandleEventsImplLocator
00379    (const System::Guts& sys, State& state, System::EventCause cause, const std::vector<EventId>& eventIds,
00380     Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols, Stage& lowestModified, bool& shouldTerminate)
00381   { return sys.handleEventsImpl(state, cause, eventIds, accuracy, yWeights, ooConstraintTols, lowestModified, shouldTerminate); }
00382 
00383 static int  systemReportEventsImplLocator
00384    (const System::Guts& sys, const State& state, System::EventCause cause, const std::vector<EventId>& eventIds)
00385   { return sys.reportEventsImpl(state, cause, eventIds); }
00386 
00387 static int  systemCalcEventTriggerInfoImplLocator(const System::Guts& sys, const State& state, std::vector<System::EventTriggerInfo>& info)
00388   { return sys.calcEventTriggerInfoImpl(state,info); }
00389 
00390 static int  systemCalcTimeOfNextScheduledEventImplLocator
00391    (const System::Guts& sys, const State& state, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime)
00392   { return sys.calcTimeOfNextScheduledEventImpl(state,tNextEvent,eventIds,includeCurrentTime); }
00393 
00394 static int  systemCalcTimeOfNextScheduledReportImplLocator
00395    (const System::Guts& sys, const State& state, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime)
00396   { return sys.calcTimeOfNextScheduledReportImpl(state,tNextEvent,eventIds,includeCurrentTime); }
00397 
00398 
00399 // Constructor must be inline so that it has access to the above static
00400 // functions which are private to the client-side compilation unit in which the
00401 // client-side virtual function table is understood.
00402 inline System::Guts::Guts(const String& name, const String& version) : rep(0)
00403 {
00404     librarySideConstruction(name, version);
00405 
00406     // Teach the library code how to call client side virtual functions by
00407     // calling through the client side compilation unit's private static
00408     // locator functions.
00409     registerDestructImpl(systemDestructImplLocator);
00410     registerCloneImpl(systemCloneImplLocator);
00411 
00412     registerRealizeTopologyImpl    (systemRealizeTopologyImplLocator);
00413     registerRealizeModelImpl       (systemRealizeModelImplLocator);
00414     registerRealizeInstanceImpl    (systemRealizeInstanceImplLocator);
00415     registerRealizeTimeImpl        (systemRealizeTimeImplLocator);
00416     registerRealizePositionImpl    (systemRealizePositionImplLocator);
00417     registerRealizeVelocityImpl    (systemRealizeVelocityImplLocator);
00418     registerRealizeDynamicsImpl    (systemRealizeDynamicsImplLocator);
00419     registerRealizeAccelerationImpl(systemRealizeAccelerationImplLocator);
00420     registerRealizeReportImpl      (systemRealizeReportImplLocator);
00421 
00422 
00423     registerCalcTimescaleImpl(systemCalcTimescaleImplLocator);
00424     registerCalcYUnitWeightsImplLocator(systemCalcYUnitWeightsImplLocator);
00425     registerProjectImpl(systemProjectImplLocator);
00426     registerCalcYErrUnitTolerancesImplLocator(systemCalcYErrUnitTolerancesImplLocator);
00427     registerHandleEventsImpl(systemHandleEventsImplLocator);
00428     registerReportEventsImpl(systemReportEventsImplLocator);
00429     registerCalcEventTriggerInfoImpl(systemCalcEventTriggerInfoImplLocator);
00430     registerCalcTimeOfNextScheduledEventImpl(systemCalcTimeOfNextScheduledEventImplLocator);
00431     registerCalcTimeOfNextScheduledReportImpl(systemCalcTimeOfNextScheduledReportImplLocator);
00432 }
00433 
00434 } // namespace SimTK
00435 
00436 #endif // SimTK_SimTKCOMMON_SYSTEM_GUTS_H_

Generated on Thu Feb 28 01:34:33 2008 for SimTKcommon by  doxygen 1.4.7