File indexing completed on 2024-09-08 03:35:52
0001 /* 0002 SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 /** \file particle.h 0008 * \brief Particle and ChargedParticle classes 0009 */ 0010 0011 #ifndef STEPCORE_PARTICLE_H 0012 #define STEPCORE_PARTICLE_H 0013 0014 #include "world.h" 0015 #include "vector.h" 0016 #include "object.h" 0017 0018 namespace StepCore { 0019 0020 class Particle; 0021 class ChargedParticle; 0022 0023 /** \ingroup errors 0024 * \brief Errors object for Particle 0025 */ 0026 class ParticleErrors: public ObjectErrors 0027 { 0028 STEPCORE_OBJECT(ParticleErrors) 0029 0030 public: 0031 /** Constructs ParticleErrors */ 0032 explicit ParticleErrors(Item* owner = nullptr) 0033 : ObjectErrors(owner), _positionVariance(0,0), _velocityVariance(0,0), 0034 _forceVariance(0,0), _massVariance(0) {} 0035 0036 /** Get owner as Particle */ 0037 Particle* particle() const; 0038 0039 /** Get position variance */ 0040 const Vector2d& positionVariance() const { return _positionVariance; } 0041 /** Set position variance */ 0042 void setPositionVariance(const Vector2d& positionVariance) { 0043 _positionVariance = positionVariance; } 0044 0045 /** Get velocity variance */ 0046 const Vector2d& velocityVariance() const { return _velocityVariance; } 0047 /** Set velocity variance */ 0048 void setVelocityVariance(const Vector2d& velocityVariance) { 0049 _velocityVariance = velocityVariance; } 0050 0051 /** Get acceleration variance */ 0052 Vector2d accelerationVariance() const; 0053 0054 /** Get force variance */ 0055 const Vector2d& forceVariance() const { return _forceVariance; } 0056 /** Set force variance */ 0057 void setForceVariance(const Vector2d& forceVariance) { 0058 _forceVariance = forceVariance; } 0059 0060 /** Increment force variance */ 0061 void applyForceVariance(const Vector2d& forceVariance) { 0062 _forceVariance += forceVariance; } 0063 0064 /** Get mass variance */ 0065 double massVariance() const { return _massVariance; } 0066 /** Set mass variance */ 0067 void setMassVariance(double massVariance) { 0068 _massVariance = massVariance; } 0069 0070 /** Get momentum variance */ 0071 Vector2d momentumVariance() const; 0072 /** Set momentum variance (will modify velocity variance) */ 0073 void setMomentumVariance(const Vector2d& momentumVariance); 0074 0075 /** Get kinetic energy variance */ 0076 double kineticEnergyVariance() const; 0077 /** Set kinetic energy variance (will modify velocity variance) */ 0078 void setKineticEnergyVariance(double kineticEnergyVariance); 0079 0080 protected: 0081 Vector2d _positionVariance; 0082 Vector2d _velocityVariance; 0083 Vector2d _forceVariance; 0084 double _massVariance; 0085 friend class Particle; 0086 }; 0087 0088 /** \ingroup bodies 0089 * \brief Particle with mass 0090 */ 0091 class Particle: public Body 0092 { 0093 STEPCORE_OBJECT(Particle) 0094 0095 public: 0096 enum { 0097 PositionOffset = 0 ///< Offset of particle position in variables array 0098 }; 0099 0100 /** Constructs a particle */ 0101 explicit Particle(const Vector2d &position = Vector2d::Zero(), 0102 const Vector2d &velocity = Vector2d::Zero(), double mass = 1); 0103 0104 /** Get position of the particle */ 0105 const Vector2d& position() const { return _position; } 0106 /** Set position of the particle */ 0107 void setPosition(const Vector2d& position) { _position = position; } 0108 0109 /** Get velocity of the particle */ 0110 const Vector2d& velocity() const { return _velocity; } 0111 /** Set velocity of the particle */ 0112 void setVelocity(const Vector2d& velocity) { _velocity = velocity; } 0113 0114 /** Get acceleration of the particle */ 0115 Vector2d acceleration() const { return _force/_mass; } 0116 0117 /** Get force that acts upon particle */ 0118 const Vector2d& force() const { return _force; } 0119 /** Set force that acts upon particle */ 0120 void setForce(const Vector2d& force) { _force = force; } 0121 0122 /** Apply force to the body */ 0123 void applyForce(const Vector2d& force) { _force += force; } 0124 0125 /** Get mass of the particle */ 0126 double mass() const { return _mass; } 0127 /** Set mass of the particle */ 0128 void setMass(double mass) { _mass = mass; } 0129 0130 /** Get momentum of the particle */ 0131 Vector2d momentum() const { return _velocity * _mass; } 0132 /** Set momentum of the particle (will modify only velocity) */ 0133 void setMomentum(const Vector2d& momentum) { _velocity = momentum / _mass; } 0134 0135 /** Get kinetic energy of the particle */ 0136 double kineticEnergy() const { return _mass * _velocity.squaredNorm()/2; } 0137 /** Set kinetic energy of the particle (will modify only velocity) */ 0138 void setKineticEnergy(double kineticEnergy); 0139 0140 int variablesCount() override { return 2; } 0141 void getVariables(double* position, double* velocity, 0142 double* positionVariance, double* velocityVariance) override; 0143 void setVariables(const double* position, const double* velocity, 0144 const double* positionVariance, const double* velocityVariance) override; 0145 void addForce(const double* force, const double* forceVariance) override; 0146 void resetForce(bool resetVariance) override; 0147 void getAccelerations(double* acceleration, double* accelerationVariance) override; 0148 void getInverseMass(VectorXd* inverseMass, 0149 DynSparseRowMatrix* variance, int offset) override; 0150 0151 /** Get (and possibly create) ParticleErrors object */ 0152 ParticleErrors* particleErrors() { 0153 return static_cast<ParticleErrors*>(objectErrors()); } 0154 0155 protected: 0156 ObjectErrors* createObjectErrors() override { return new ParticleErrors(this); } 0157 0158 Vector2d _position; 0159 Vector2d _velocity; 0160 Vector2d _force; 0161 double _mass; 0162 }; 0163 0164 /** \ingroup errors 0165 * \brief Errors object for ChargedParticle 0166 */ 0167 class ChargedParticleErrors: public ParticleErrors 0168 { 0169 STEPCORE_OBJECT(ChargedParticleErrors) 0170 0171 public: 0172 /** Constructs ChargedParticleErrors */ 0173 explicit ChargedParticleErrors(Item* owner = nullptr) 0174 : ParticleErrors(owner), _chargeVariance(0) {} 0175 0176 /** Get owner as ChargedParticle */ 0177 ChargedParticle* chargedParticle() const; 0178 0179 /** Get charge variance */ 0180 double chargeVariance() const { return _chargeVariance; } 0181 /** Set charge variance */ 0182 void setChargeVariance(double chargeVariance) { 0183 _chargeVariance = chargeVariance; } 0184 0185 protected: 0186 double _chargeVariance; 0187 friend class ChargedParticle; 0188 }; 0189 0190 0191 /** \ingroup bodies 0192 * \brief ChargedParticle with mass and charge 0193 */ 0194 class ChargedParticle: public Particle 0195 { 0196 STEPCORE_OBJECT(ChargedParticle) 0197 0198 public: 0199 /** Constructs a charged particle */ 0200 explicit ChargedParticle(const Vector2d &position = Vector2d::Zero(), 0201 const Vector2d &velocity = Vector2d::Zero(), double mass = 1, double charge = 0) 0202 : Particle(position, velocity, mass), _charge(charge) {} 0203 0204 /** Charge of the particle */ 0205 double charge() const { return _charge; } 0206 /** Charge of the particle */ 0207 void setCharge(double charge) { _charge = charge; } 0208 0209 /** Get (and possibly create) ChargedParticleErrors object */ 0210 ChargedParticleErrors* chargedParticleErrors() { 0211 return static_cast<ChargedParticleErrors*>(objectErrors()); } 0212 0213 protected: 0214 ObjectErrors* createObjectErrors() override { return new ChargedParticleErrors(this); } 0215 0216 double _charge; 0217 }; 0218 0219 } // namespace StepCore 0220 0221 #endif 0222