MassCenterMotionRemover.h
Go to the documentation of this file.00001 #ifndef SimTK_MASS_CENTER_MOTION_REMOVER_H_
00002 #define SimTK_MASS_CENTER_MOTION_REMOVER_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "SimTKsimbody.h"
00035 #include "molmodel/internal/common.h"
00036 #include "molmodel/internal/MolecularMechanicsSystem.h"
00037
00038 namespace SimTK {
00039
00050 class MassCenterMotionRemover
00051 : public PeriodicEventHandler {
00052 public:
00069 explicit MassCenterMotionRemover(const MolecularMechanicsSystem& system,
00070 Real adjustmentInterval = 1)
00071 : PeriodicEventHandler(adjustmentInterval),
00072 system(system), linearMomOnly(false),
00073 enableCOMCorrection(false), comTol(1), comPos(0)
00074 {
00075 }
00076
00088 MassCenterMotionRemover& disableAngularMomentumRemoval(bool disable)
00089 { linearMomOnly = disable; return *this; }
00095 bool isAngularMomentumRemovalDisabled() const {return linearMomOnly;}
00096
00112 MassCenterMotionRemover& enableMassCenterCorrection(bool enabled)
00113 { enableCOMCorrection = enabled; return *this; }
00119 bool isMassCenterCorrectionEnabled() const {return enableCOMCorrection;}
00120
00136 MassCenterMotionRemover&
00137 setDesiredMassCenterLocation(const Vec3& groundLocationInNm)
00138 { comPos = groundLocationInNm; return *this; }
00144 const Vec3& getDesiredMassCenterLocation() const {return comPos;}
00145
00164 MassCenterMotionRemover&
00165 setMassCenterLocationTolerance(Real toleranceInNm) {
00166 SimTK_APIARGCHECK1_ALWAYS(toleranceInNm > 0,
00167 "MassCenterMotionRemover","setMassCenterLocationTolerance",
00168 "Illegal mass center tolerance %g.", toleranceInNm);
00169 comTol = toleranceInNm;
00170 return *this;
00171 }
00177 Real getMassCenterLocationTolerance() const {return comTol;}
00178
00187 void removeSystemMomentum(State& state) const
00188 { system.removeSystemRigidBodyMomentum(state, linearMomOnly); }
00189
00199 void correctMassCenterLocation(State& state) const
00200 { system.moveSystemMassCenter(state, comPos); }
00201
00214 Real calcMassCenterError(const State& state) const
00215 { return (system.calcSystemMassCenterLocation(state) - comPos).norm(); }
00216
00217
00218
00219
00221 void handleEvent(State& state, Real accuracy,
00222 const Vector& yWeights, const Vector& ooConstraintTols,
00223 Stage& lowestModified, bool& shouldTerminate) const
00224 {
00225 system.realize(state, Stage::Velocity);
00226 removeSystemMomentum(state);
00227 lowestModified = Stage::Velocity;
00228 if (enableCOMCorrection && calcMassCenterError(state) > comTol) {
00229 correctMassCenterLocation(state);
00230 lowestModified = Stage::Position;
00231 }
00232 }
00234
00235 private:
00236 const MolecularMechanicsSystem& system;
00237 bool linearMomOnly;
00238 bool enableCOMCorrection;
00239 Real comTol;
00240 Vec3 comPos;
00241 };
00242
00243 }
00244
00245 #endif // SimTK_MASS_CENTER_MOTION_REMOVER_H_