Simbody
3.4 (development)
|
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-12 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 00038 00061 class SimTK_SimTKCOMMON_EXPORT Subsystem { 00062 public: 00063 class Guts; // local; name is Subsystem::Guts 00064 friend class Guts; 00065 private: 00066 // This is the only data member in this class. Also, any class derived from 00067 // Subsystem must have *NO* data members at all (data goes in the Guts class). 00068 Guts* guts; 00069 public: 00070 Subsystem() : guts(0) { } // an empty handle 00071 Subsystem(const Subsystem&); 00072 Subsystem& operator=(const Subsystem&); 00073 ~Subsystem(); 00074 00075 const String& getName() const; 00076 const String& getVersion() const; 00077 00078 // These call the corresponding State method, supplying this Subsystem's 00079 // SubsystemIndex. The returned indices are local to this Subsystem. 00080 QIndex allocateQ(State&, const Vector& qInit) const; 00081 UIndex allocateU(State&, const Vector& uInit) const; 00082 ZIndex allocateZ(State&, const Vector& zInit) const; 00083 00084 DiscreteVariableIndex allocateDiscreteVariable 00085 (State&, Stage invalidates, AbstractValue* v) const; 00086 DiscreteVariableIndex allocateAutoUpdateDiscreteVariable 00087 (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const; 00088 00089 CacheEntryIndex allocateCacheEntry 00090 (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const; 00091 CacheEntryIndex allocateCacheEntry 00092 (const State& state, Stage g, AbstractValue* v) const 00093 { return allocateCacheEntry(state, g, g, v); } 00094 CacheEntryIndex allocateLazyCacheEntry 00095 (const State& state, Stage earliest, AbstractValue* v) const 00096 { return allocateCacheEntry(state, earliest, Stage::Infinity, v); } 00097 00098 QErrIndex allocateQErr (const State&, int nqerr) const; 00099 UErrIndex allocateUErr (const State&, int nuerr) const; 00100 UDotErrIndex allocateUDotErr (const State&, int nudoterr) const; 00101 EventTriggerByStageIndex allocateEventTriggersByStage 00102 (const State&, Stage, int ntriggers) const; 00103 00104 // These return views on State shared global resources. The views 00105 // are private to this subsystem, but the global resources themselves 00106 // are not allocated until the *System* advances to stage Model. 00107 // Note that there is no subsystem equivalent of the State's "y" 00108 // vector because in general a subsystem's state variables will 00109 // not be contiguous. However, a subsystem's q's, u's, and z's 00110 // will all be contiguous within those arrays. 00111 const Vector& getQ(const State&) const; 00112 const Vector& getU(const State&) const; 00113 const Vector& getZ(const State&) const; 00114 const Vector& getQDot(const State&) const; 00115 const Vector& getUDot(const State&) const; 00116 const Vector& getZDot(const State&) const; 00117 const Vector& getQDotDot(const State&) const; 00118 const Vector& getQErr(const State&) const; 00119 const Vector& getUErr(const State&) const; 00120 const Vector& getUDotErr(const State&) const; 00121 const Vector& getMultipliers(const State&) const; 00122 const Vector& getEventTriggersByStage(const State&, Stage) const; 00123 00124 // These return writable access to this subsystem's partition in the 00125 // State pool of continuous variables. These can be called at Stage::Model 00126 // or higher, and if necesary they invalidate the Position (q), Velocity (u), 00127 // or Dynamics (z) stage respectively. 00128 Vector& updQ(State&) const; // invalidates Stage::Position 00129 Vector& updU(State&) const; // invalidates Stage::Velocity 00130 Vector& updZ(State&) const; // invalidates Stage::Dynamics 00131 00132 // For convenience. 00133 void setQ(State& s, const Vector& q) const { 00134 assert(q.size() == getNQ(s)); 00135 updQ(s) = q; 00136 } 00137 void setU(State& s, const Vector& u) const { 00138 assert(u.size() == getNU(s)); 00139 updU(s) = u; 00140 } 00141 void setZ(State& s, const Vector& z) const { 00142 assert(z.size() == getNZ(s)); 00143 updZ(s) = z; 00144 } 00145 00146 // These update the State cache which is mutable; hence, const State. They 00147 // can be called only if the previous stage has already been realized, e.g., 00148 // updQDot() is allowed only while realizing the Velocity stage, requiring 00149 // that Position stage has already been realized. 00150 Vector& updQDot(const State&) const; 00151 Vector& updUDot(const State&) const; 00152 Vector& updZDot(const State&) const; 00153 Vector& updQDotDot(const State&) const; 00154 Vector& updQErr(const State&) const; 00155 Vector& updUErr(const State&) const; 00156 Vector& updUDotErr(const State&) const; 00157 Vector& updMultipliers(const State&) const; 00158 Vector& updEventTriggersByStage(const State&, Stage) const; 00159 00160 // These pull out the State entries which belong exclusively to 00161 // this Subsystem. These variables and cache entries are available 00162 // as soon as this subsystem is at stage Model. 00163 Stage getStage(const State&) const; 00164 const AbstractValue& getDiscreteVariable(const State& s, DiscreteVariableIndex dx) const; 00165 00166 Real getDiscreteVarLastUpdateTime(const State& s, DiscreteVariableIndex dx) const 00167 { return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); } 00168 CacheEntryIndex getDiscreteVarUpdateIndex(const State& s, DiscreteVariableIndex dx) const 00169 { return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); } 00170 const AbstractValue& getDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const 00171 { return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); } 00172 AbstractValue& updDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const 00173 { return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); } 00174 bool isDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const 00175 { return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); } 00176 void markDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const 00177 { return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); } 00178 00179 // State is *not* mutable here -- must have write access to change state variables. 00180 AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const; 00181 00182 const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const; 00183 // State is mutable here. 00184 AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const; 00185 00186 bool isCacheValueRealized(const State&, CacheEntryIndex) const; 00187 void markCacheValueRealized(const State&, CacheEntryIndex) const; 00188 void markCacheValueNotRealized(const State&, CacheEntryIndex) const; 00189 00190 // Dimensions. These are valid at System Stage::Model while access to the 00191 // various arrays may have stricter requirements. Hence it is better to use 00192 // these routines than to get a reference to a Vector above and ask for 00193 // its size(). 00194 00195 SystemQIndex getQStart (const State&) const; 00196 int getNQ (const State&) const; 00197 SystemUIndex getUStart (const State&) const; 00198 int getNU (const State&) const; 00199 SystemZIndex getZStart (const State&) const; 00200 int getNZ (const State&) const; 00201 SystemQErrIndex getQErrStart (const State&) const; 00202 int getNQErr (const State&) const; 00203 SystemUErrIndex getUErrStart (const State&) const; 00204 int getNUErr (const State&) const; 00205 SystemUDotErrIndex getUDotErrStart(const State&) const; 00206 int getNUDotErr (const State&) const; 00207 SystemMultiplierIndex getMultipliersStart (const State&) const; 00208 int getNMultipliers (const State&) const; 00209 SystemEventTriggerByStageIndex getEventTriggerStartByStage(const State&, Stage) const; 00210 int getNEventTriggersByStage (const State&, Stage) const; 00211 00212 bool isInSystem() const; 00213 bool isInSameSystem(const Subsystem& otherSubsystem) const; 00214 00215 const System& getSystem() const; 00216 System& updSystem(); 00217 00218 SubsystemIndex getMySubsystemIndex() const; 00219 00220 // Is this handle the owner of this rep? This is true if the 00221 // handle is empty or if its rep points back here. 00222 bool isOwnerHandle() const; 00223 bool isEmptyHandle() const; 00224 00225 // There can be multiple handles on the same Subsystem. 00226 bool isSameSubsystem(const Subsystem& otherSubsystem) const; 00227 00228 bool subsystemTopologyHasBeenRealized() const; 00229 void invalidateSubsystemTopologyCache() const; 00230 00231 // Add a new Measure to this Subsystem. This method is generally used by Measure 00232 // constructors to install a newly-constructed Measure into its Subsystem. 00233 MeasureIndex adoptMeasure(AbstractMeasure&); 00234 00235 AbstractMeasure getMeasure(MeasureIndex) const; 00236 template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const 00237 { return Measure_<T>::getAs(getMeasure(mx));} 00238 00239 // dynamic_cast the returned reference to a reference to your concrete Guts 00240 // class. 00241 const Subsystem::Guts& getSubsystemGuts() const {assert(guts); return *guts;} 00242 Subsystem::Guts& updSubsystemGuts() {assert(guts); return *guts;} 00243 00244 // Put new Guts into this *empty* handle and take over ownership. 00245 // If this handle is already in use, this routine will throw 00246 // an exception. 00247 void adoptSubsystemGuts(Subsystem::Guts* g); 00248 void setSystem(System&, SubsystemIndex); 00249 00250 explicit Subsystem(Subsystem::Guts* g) : guts(g) { } 00251 bool hasGuts() const {return guts!=0;} 00252 }; 00253 00254 } // namespace SimTK 00255 00256 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_H_