1 /* This file is part of StepCore library. 2 Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com> 3 4 StepCore library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 StepCore library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with StepCore; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 /** \file particle.h 20 * \brief Particle and ChargedParticle classes 21 */ 22 23 #ifndef STEPCORE_PARTICLE_H 24 #define STEPCORE_PARTICLE_H 25 26 #include "world.h" 27 #include "vector.h" 28 #include "object.h" 29 30 namespace StepCore { 31 32 class Particle; 33 class ChargedParticle; 34 35 /** \ingroup errors 36 * \brief Errors object for Particle 37 */ 38 class ParticleErrors: public ObjectErrors 39 { STEPCORE_OBJECT(ParticleErrors)40 STEPCORE_OBJECT(ParticleErrors) 41 42 public: 43 /** Constructs ParticleErrors */ 44 explicit ParticleErrors(Item* owner = 0) 45 : ObjectErrors(owner), _positionVariance(0,0), _velocityVariance(0,0), 46 _forceVariance(0,0), _massVariance(0) {} 47 48 /** Get owner as Particle */ 49 Particle* particle() const; 50 51 /** Get position variance */ positionVariance()52 const Vector2d& positionVariance() const { return _positionVariance; } 53 /** Set position variance */ setPositionVariance(const Vector2d & positionVariance)54 void setPositionVariance(const Vector2d& positionVariance) { 55 _positionVariance = positionVariance; } 56 57 /** Get velocity variance */ velocityVariance()58 const Vector2d& velocityVariance() const { return _velocityVariance; } 59 /** Set velocity variance */ setVelocityVariance(const Vector2d & velocityVariance)60 void setVelocityVariance(const Vector2d& velocityVariance) { 61 _velocityVariance = velocityVariance; } 62 63 /** Get acceleration variance */ 64 Vector2d accelerationVariance() const; 65 66 /** Get force variance */ forceVariance()67 const Vector2d& forceVariance() const { return _forceVariance; } 68 /** Set force variance */ setForceVariance(const Vector2d & forceVariance)69 void setForceVariance(const Vector2d& forceVariance) { 70 _forceVariance = forceVariance; } 71 72 /** Increment force variance */ applyForceVariance(const Vector2d & forceVariance)73 void applyForceVariance(const Vector2d& forceVariance) { 74 _forceVariance += forceVariance; } 75 76 /** Get mass variance */ massVariance()77 double massVariance() const { return _massVariance; } 78 /** Set mass variance */ setMassVariance(double massVariance)79 void setMassVariance(double massVariance) { 80 _massVariance = massVariance; } 81 82 /** Get momentum variance */ 83 Vector2d momentumVariance() const; 84 /** Set momentum variance (will modify velocity variance) */ 85 void setMomentumVariance(const Vector2d& momentumVariance); 86 87 /** Get kinetic energy variance */ 88 double kineticEnergyVariance() const; 89 /** Set kinetic energy variance (will modify velocity variance) */ 90 void setKineticEnergyVariance(double kineticEnergyVariance); 91 92 protected: 93 Vector2d _positionVariance; 94 Vector2d _velocityVariance; 95 Vector2d _forceVariance; 96 double _massVariance; 97 friend class Particle; 98 }; 99 100 /** \ingroup bodies 101 * \brief Particle with mass 102 */ 103 class Particle: public Body 104 { 105 STEPCORE_OBJECT(Particle) 106 107 public: 108 enum { 109 PositionOffset = 0 ///< Offset of particle position in variables array 110 }; 111 112 /** Constructs a particle */ 113 explicit Particle(const Vector2d &position = Vector2d::Zero(), 114 const Vector2d &velocity = Vector2d::Zero(), double mass = 1); 115 116 /** Get position of the particle */ position()117 const Vector2d& position() const { return _position; } 118 /** Set position of the particle */ setPosition(const Vector2d & position)119 void setPosition(const Vector2d& position) { _position = position; } 120 121 /** Get velocity of the particle */ velocity()122 const Vector2d& velocity() const { return _velocity; } 123 /** Set velocity of the particle */ setVelocity(const Vector2d & velocity)124 void setVelocity(const Vector2d& velocity) { _velocity = velocity; } 125 126 /** Get acceleration of the particle */ acceleration()127 Vector2d acceleration() const { return _force/_mass; } 128 129 /** Get force that acts upon particle */ force()130 const Vector2d& force() const { return _force; } 131 /** Set force that acts upon particle */ setForce(const Vector2d & force)132 void setForce(const Vector2d& force) { _force = force; } 133 134 /** Apply force to the body */ applyForce(const Vector2d & force)135 void applyForce(const Vector2d& force) { _force += force; } 136 137 /** Get mass of the particle */ mass()138 double mass() const { return _mass; } 139 /** Set mass of the particle */ setMass(double mass)140 void setMass(double mass) { _mass = mass; } 141 142 /** Get momentum of the particle */ momentum()143 Vector2d momentum() const { return _velocity * _mass; } 144 /** Set momentum of the particle (will modify only velocity) */ setMomentum(const Vector2d & momentum)145 void setMomentum(const Vector2d& momentum) { _velocity = momentum / _mass; } 146 147 /** Get kinetic energy of the particle */ kineticEnergy()148 double kineticEnergy() const { return _mass * _velocity.squaredNorm()/2; } 149 /** Set kinetic energy of the particle (will modify only velocity) */ 150 void setKineticEnergy(double kineticEnergy); 151 variablesCount()152 int variablesCount() override { return 2; } 153 void getVariables(double* position, double* velocity, 154 double* positionVariance, double* velocityVariance) override; 155 void setVariables(const double* position, const double* velocity, 156 const double* positionVariance, const double* velocityVariance) override; 157 void addForce(const double* force, const double* forceVariance) override; 158 void resetForce(bool resetVariance) override; 159 void getAccelerations(double* acceleration, double* accelerationVariance) override; 160 void getInverseMass(VectorXd* inverseMass, 161 DynSparseRowMatrix* variance, int offset) override; 162 163 /** Get (and possibly create) ParticleErrors object */ particleErrors()164 ParticleErrors* particleErrors() { 165 return static_cast<ParticleErrors*>(objectErrors()); } 166 167 protected: createObjectErrors()168 ObjectErrors* createObjectErrors() override { return new ParticleErrors(this); } 169 170 Vector2d _position; 171 Vector2d _velocity; 172 Vector2d _force; 173 double _mass; 174 }; 175 176 /** \ingroup errors 177 * \brief Errors object for ChargedParticle 178 */ 179 class ChargedParticleErrors: public ParticleErrors 180 { STEPCORE_OBJECT(ChargedParticleErrors)181 STEPCORE_OBJECT(ChargedParticleErrors) 182 183 public: 184 /** Constructs ChargedParticleErrors */ 185 explicit ChargedParticleErrors(Item* owner = 0) 186 : ParticleErrors(owner), _chargeVariance(0) {} 187 188 /** Get owner as ChargedParticle */ 189 ChargedParticle* chargedParticle() const; 190 191 /** Get charge variance */ chargeVariance()192 double chargeVariance() const { return _chargeVariance; } 193 /** Set charge variance */ setChargeVariance(double chargeVariance)194 void setChargeVariance(double chargeVariance) { 195 _chargeVariance = chargeVariance; } 196 197 protected: 198 double _chargeVariance; 199 friend class ChargedParticle; 200 }; 201 202 203 /** \ingroup bodies 204 * \brief ChargedParticle with mass and charge 205 */ 206 class ChargedParticle: public Particle 207 { STEPCORE_OBJECT(ChargedParticle)208 STEPCORE_OBJECT(ChargedParticle) 209 210 public: 211 /** Constructs a charged particle */ 212 explicit ChargedParticle(const Vector2d &position = Vector2d::Zero(), 213 const Vector2d &velocity = Vector2d::Zero(), double mass = 1, double charge = 0) 214 : Particle(position, velocity, mass), _charge(charge) {} 215 216 /** Charge of the particle */ charge()217 double charge() const { return _charge; } 218 /** Charge of the particle */ setCharge(double charge)219 void setCharge(double charge) { _charge = charge; } 220 221 /** Get (and possibly create) ChargedParticleErrors object */ chargedParticleErrors()222 ChargedParticleErrors* chargedParticleErrors() { 223 return static_cast<ChargedParticleErrors*>(objectErrors()); } 224 225 protected: createObjectErrors()226 ObjectErrors* createObjectErrors() override { return new ChargedParticleErrors(this); } 227 228 double _charge; 229 }; 230 231 } // namespace StepCore 232 233 #endif 234 235