Simbody
3.5
|
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_