Simbody  3.5
Subsystem.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_H_
00002 #define SimTK_SimTKCOMMON_SUBSYSTEM_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK 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/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-14 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00027 #include "SimTKcommon/basics.h"
00028 #include "SimTKcommon/Simmatrix.h"
00029 #include "SimTKcommon/internal/State.h"
00030 #include "SimTKcommon/internal/Measure.h"
00031 
00032 #include <cassert>
00033 
00034 namespace SimTK {
00035 
00036 class System;
00037 
00055 class SimTK_SimTKCOMMON_EXPORT Subsystem {
00056 public:
00057 class Guts; // local; name is Subsystem::Guts
00058 friend class Guts;
00059 
00062 Subsystem() : guts(0) {}
00063 
00067 Subsystem(const Subsystem&);
00070 Subsystem& operator=(const Subsystem&);
00071 
00076 ~Subsystem();
00077 
00078 
00088 QIndex allocateQ(State& s, const Vector& qInit) const 
00089 {   return s.allocateQ(getMySubsystemIndex(), qInit); }
00090 UIndex allocateU(State& s, const Vector& uInit) const 
00091 {   return s.allocateU(getMySubsystemIndex(), uInit); }
00092 ZIndex allocateZ(State& s, const Vector& zInit) const 
00093 {   return s.allocateZ(getMySubsystemIndex(), zInit); }
00094 
00095 DiscreteVariableIndex 
00096 allocateDiscreteVariable(State& s, Stage g, AbstractValue* v) const 
00097 {   return s.allocateDiscreteVariable(getMySubsystemIndex(), g, v); }
00098 DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
00099    (State& s, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const
00100 {   return s.allocateAutoUpdateDiscreteVariable
00101                (getMySubsystemIndex(),invalidates,v,updateDependsOn); }
00102 CacheEntryIndex allocateCacheEntry
00103    (const State& s, Stage dependsOn, Stage computedBy, AbstractValue* v) const 
00104 {   return s.allocateCacheEntry
00105                (getMySubsystemIndex(), dependsOn, computedBy, v); }
00106 
00107 CacheEntryIndex allocateCacheEntry
00108     (const State& state, Stage g, AbstractValue* v) const 
00109 {   return allocateCacheEntry(state, g, g, v); }
00110 CacheEntryIndex allocateLazyCacheEntry   
00111     (const State& state, Stage earliest, AbstractValue* v) const 
00112 {   return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
00113 
00114 QErrIndex allocateQErr(const State& s, int nqerr) const 
00115 {   return s.allocateQErr(getMySubsystemIndex(), nqerr); }
00116 UErrIndex allocateUErr(const State& s, int nuerr) const 
00117 {   return s.allocateUErr(getMySubsystemIndex(), nuerr); }
00118 UDotErrIndex allocateUDotErr(const State& s, int nudoterr) const 
00119 {   return s.allocateUDotErr(getMySubsystemIndex(), nudoterr); }
00120 EventTriggerByStageIndex 
00121 allocateEventTriggersByStage(const State& s, Stage g, int ntriggers) const 
00122 {   return s.allocateEventTrigger(getMySubsystemIndex(),g,ntriggers); }
00123 
00124 const Vector& getQ(const State& s) const 
00125 {   return s.getQ(getMySubsystemIndex()); }
00126 const Vector& getU(const State& s) const 
00127 {   return s.getU(getMySubsystemIndex()); }
00128 const Vector& getZ(const State& s) const 
00129 {   return s.getZ(getMySubsystemIndex()); }
00130 const Vector& getUWeights(const State& s) const 
00131 {   return s.getUWeights(getMySubsystemIndex()); }
00132 const Vector& getZWeights(const State& s) const 
00133 {   return s.getZWeights(getMySubsystemIndex()); }
00134 
00135 Vector& updQ(State& s) const {return s.updQ(getMySubsystemIndex());}
00136 Vector& updU(State& s) const {return s.updU(getMySubsystemIndex());}
00137 Vector& updZ(State& s) const {return s.updZ(getMySubsystemIndex());}
00138 
00139 const Vector& getQDot   (const State& s) const 
00140 {   return s.getQDot(getMySubsystemIndex()); }
00141 const Vector& getUDot   (const State& s) const 
00142 {   return s.getUDot(getMySubsystemIndex()); }
00143 const Vector& getZDot   (const State& s) const 
00144 {   return s.getZDot(getMySubsystemIndex()); }
00145 const Vector& getQDotDot(const State& s) const 
00146 {   return s.getQDotDot(getMySubsystemIndex()); }
00147 
00148 Vector& updQDot   (const State& s) const 
00149 {   return s.updQDot(getMySubsystemIndex()); }
00150 Vector& updUDot   (const State& s) const 
00151 {   return s.updUDot(getMySubsystemIndex()); }
00152 Vector& updZDot   (const State& s) const 
00153 {   return s.updZDot(getMySubsystemIndex()); }
00154 Vector& updQDotDot(const State& s) const 
00155 {   return s.updQDotDot(getMySubsystemIndex()); }
00156 
00157 const Vector& getQErr(const State& s) const 
00158 {   return s.getQErr(getMySubsystemIndex()); }
00159 const Vector& getUErr(const State& s) const 
00160 {   return s.getUErr(getMySubsystemIndex()); }
00161 const Vector& getQErrWeights(const State& s) const 
00162 {   return s.getQErrWeights(getMySubsystemIndex()); }
00163 const Vector& getUErrWeights(const State& s) const 
00164 {   return s.getUErrWeights(getMySubsystemIndex()); }
00165 
00166 const Vector& getUDotErr(const State& s) const 
00167 {   return s.getUDotErr(getMySubsystemIndex()); }
00168 const Vector& getMultipliers(const State& s) const 
00169 {   return s.getMultipliers(getMySubsystemIndex()); }
00170 const Vector& getEventTriggersByStage(const State& s, Stage g) const
00171 {   return s.getEventTriggersByStage(getMySubsystemIndex(),g); }
00172 
00173 Vector& updQErr(const State& s) const 
00174 {   return s.updQErr(getMySubsystemIndex()); }
00175 Vector& updUErr(const State& s) const 
00176 {   return s.updUErr(getMySubsystemIndex()); }
00177 Vector& updUDotErr(const State& s) const 
00178 {   return s.updUDotErr(getMySubsystemIndex()); }
00179 Vector& updMultipliers(const State& s) const 
00180 {   return s.updMultipliers(getMySubsystemIndex()); }
00181 Vector& updEventTriggersByStage(const State& s, Stage g) const
00182 {   return s.updEventTriggersByStage(getMySubsystemIndex(),g); }
00183 
00184 SystemQIndex getQStart(const State& s) const 
00185 {   return s.getQStart(getMySubsystemIndex()); }
00186 int getNQ(const State& s)     const 
00187 {   return s.getNQ(getMySubsystemIndex()); }
00188 
00189 SystemUIndex getUStart(const State& s) const 
00190 {   return s.getUStart(getMySubsystemIndex()); }
00191 int getNU(const State& s)     const 
00192 {   return s.getNU(getMySubsystemIndex()); }
00193 
00194 SystemZIndex getZStart(const State& s) const 
00195 {   return s.getZStart(getMySubsystemIndex()); }
00196 int getNZ(const State& s)     const 
00197 {   return s.getNZ(getMySubsystemIndex()); }
00198 
00199 SystemQErrIndex getQErrStart(const State& s) const 
00200 {   return s.getQErrStart(getMySubsystemIndex()); }
00201 int getNQErr(const State& s) const 
00202 {   return s.getNQErr(getMySubsystemIndex()); }
00203 
00204 SystemUErrIndex getUErrStart(const State& s) const 
00205 {   return s.getUErrStart(getMySubsystemIndex()); }
00206 int getNUErr(const State& s)     const 
00207 {   return s.getNUErr(getMySubsystemIndex()); }
00208 
00209 SystemUDotErrIndex getUDotErrStart(const State& s) const 
00210 {   return s.getUDotErrStart(getMySubsystemIndex()); }
00211 int getNUDotErr(const State& s)     const 
00212 {   return s.getNUDotErr(getMySubsystemIndex()); }
00213 
00214 SystemMultiplierIndex getMultipliersStart(const State& s) const 
00215 {   return s.getMultipliersStart(getMySubsystemIndex()); }
00216 int getNMultipliers(const State& s)     const 
00217 {   return s.getNMultipliers(getMySubsystemIndex()); }
00218 
00219 SystemEventTriggerByStageIndex getEventTriggerStartByStage(const State& s, Stage g) const 
00220 {   return s.getEventTriggerStartByStage(getMySubsystemIndex(),g); }
00221 int getNEventTriggersByStage   (const State& s, Stage g) const 
00222 {   return s.getNEventTriggersByStage(getMySubsystemIndex(),g); }
00223 
00224 
00225 // For convenience.
00226 void setQ(State& s, const Vector& q) const {
00227     SimTK_ASSERT(q.size() == getNQ(s), "Subsystem::Guts::setQ()");
00228     updQ(s) = q;
00229 }
00230 void setU(State& s, const Vector& u) const {
00231     SimTK_ASSERT(u.size() == getNU(s), "Subsystem::Guts::setU()");
00232     updU(s) = u;
00233 }
00234 void setZ(State& s, const Vector& z) const {
00235     SimTK_ASSERT(z.size() == getNZ(s), "Subsystem::Guts::setZ()");
00236     updZ(s) = z;
00237 }
00238 
00239 Stage getStage(const State& s) const 
00240 {   return s.getSubsystemStage(getMySubsystemIndex()); }
00241 void advanceToStage(const State& s, Stage g) const 
00242 {   s.advanceSubsystemToStage(getMySubsystemIndex(), g); }
00243 
00244 const AbstractValue& 
00245 getDiscreteVariable(const State& s, DiscreteVariableIndex index) const 
00246 {   return s.getDiscreteVariable(getMySubsystemIndex(), index); }
00247 AbstractValue& updDiscreteVariable(State& s, DiscreteVariableIndex index) const 
00248 {   return s.updDiscreteVariable(getMySubsystemIndex(), index); }
00249 const AbstractValue& getCacheEntry(const State& s, CacheEntryIndex index) const 
00250 {   return s.getCacheEntry(getMySubsystemIndex(), index); }
00251 AbstractValue& updCacheEntry(const State& s, CacheEntryIndex index) const 
00252 {   return s.updCacheEntry(getMySubsystemIndex(), index); }
00253 Real getDiscreteVarLastUpdateTime(const State& s, DiscreteVariableIndex dx) const
00254 {   return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
00255 CacheEntryIndex 
00256 getDiscreteVarUpdateIndex(const State& s, DiscreteVariableIndex dx) const
00257 {   return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
00258 const AbstractValue& 
00259 getDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00260 {   return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00261 AbstractValue& 
00262 updDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00263 {   return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00264 bool isDiscreteVarUpdateValueRealized
00265    (const State& s, DiscreteVariableIndex dx) const
00266 {   return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00267 void markDiscreteVarUpdateValueRealized
00268    (const State& s, DiscreteVariableIndex dx) const
00269 {   return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00270 
00271 bool isCacheValueRealized(const State& s, CacheEntryIndex cx) const 
00272 {   return s.isCacheValueRealized(getMySubsystemIndex(), cx); }
00273 void markCacheValueRealized(const State& s, CacheEntryIndex cx) const 
00274 {   s.markCacheValueRealized(getMySubsystemIndex(), cx); }
00275 void markCacheValueNotRealized(const State& s, CacheEntryIndex cx) const 
00276 {   s.markCacheValueNotRealized(getMySubsystemIndex(), cx); }
00288 inline const String& getName()    const;
00291 inline const String& getVersion() const;
00292 
00294 inline bool isInSystem() const;
00298 inline bool isInSameSystem(const Subsystem& otherSubsystem) const;
00299 
00303 inline const System& getSystem() const;
00307 inline System& updSystem();
00310 inline void setSystem(System& system, SubsystemIndex subx);
00311 
00314 inline SubsystemIndex getMySubsystemIndex() const;
00315 
00317 inline bool isEmptyHandle() const {return guts==0;}
00318 
00322 inline bool isSameSubsystem(const Subsystem& otherSubsystem) const
00323 {   return guts && (guts==otherSubsystem.guts); }
00324 
00328 inline bool isOwnerHandle() const; 
00329 
00333 inline bool subsystemTopologyHasBeenRealized() const;
00342 inline void invalidateSubsystemTopologyCache() const;
00343 
00344 // Add a new Measure to this Subsystem. This method is generally used by Measure
00345 // constructors to install a newly-constructed Measure into its Subsystem.
00346 inline MeasureIndex adoptMeasure(AbstractMeasure&);
00347 inline AbstractMeasure getMeasure(MeasureIndex) const;
00348 template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
00349 {   return Measure_<T>::getAs(getMeasure(mx));}
00350 
00351 // dynamic_cast the returned reference to a reference to your concrete Guts
00352 // class.
00353 const Subsystem::Guts& getSubsystemGuts() const {assert(guts); return *guts;}
00354 Subsystem::Guts&       updSubsystemGuts()       {assert(guts); return *guts;}
00355 
00356 // Put new Guts into this *empty* handle and take over ownership.
00357 // If this handle is already in use, this routine will throw
00358 // an exception.
00359 void adoptSubsystemGuts(Subsystem::Guts* g);
00360 
00361 explicit Subsystem(Subsystem::Guts* g) : guts(g) { }
00362 bool hasGuts() const {return guts!=0;}
00365 private:
00366 // This is the only data member in this class. Also, any class derived from
00367 // Subsystem must have *NO* data members at all (data goes in the Guts 
00368 // class).
00369 Guts* guts;
00370 };
00371 
00372 } // namespace SimTK
00373 
00374 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines