File indexing completed on 2024-04-21 03:51:23

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