Skip to content
Snippets Groups Projects
Select Git revision
  • 071725725aee4e53e75f994ff0c3ee4eb8b11394
  • main default protected
2 results

Particle.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Particle.h 7.39 KiB
    /*
     * Particle.h
     *
     * Author:
     *       Oleg Kalashev
     *
     * Copyright (c) 2020 Institute for Nuclear Research, RAS
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
    #ifndef PARTICLE_H
    #define	PARTICLE_H
    
    #include "Cosmology.h"
    #include <cstring>
    #include "Units.h"
    #include <math.h>
    
    namespace mcray
    {
        enum ParticleType
        {// order of masses in the array Particle::massesMeV must follow the order of particles below
            Electron = 0,
            Positron,
            Photon,
        	NeutrinoE,
        	NeutrinoM,
        	NeutrinoT,
        	NeutrinoAE,
        	NeutrinoAM,
        	NeutrinoAT,
        	Neutron,
        	Proton,
            EndLightParticle,
            StartNuclei = EndLightParticle,
            A02 = StartNuclei,
            A03,
            A04,
            A05,
            A06,
            A07,
            A08,
            A09,
            A10,
            A11,
            A12,
            A13,
            A14,
            A15,
            A16,
            A17,
            A18,
            A19,
            A20,
            A21,
            A22,
            A23,
            A24,
            A25,
            A26,
            A27,
            A28,
            A29,
            A30,
            A31,
            A32,
            A33,
            A34,
            A35,
            A36,
            A37,
            A38,
            A39,
            A40,
            A41,
            A42,
            A43,
            A44,
            A45,
            A46,
            A47,
            A48,
            A49,
            A50,
            A51,
            A52,
            A53,
            A54,
            A55,
            A56,
            EndNuclei,
            ParticleTypeEOF = EndNuclei //must be the last
        };
    
        typedef cosmo_time coord_type;
    
    #define ParticleCustomDataSize 16
        class Particle
        {
        private:
        	inline void Reset() {
                memset(this,0,sizeof(Particle));Weight=1.; LastB = -1.; Pdir[2]=1.;
            }
            void GenerateId();
        public:
        	inline double Mass() const {
                return Mass(Type);
            }
        	inline int ElectricCharge() const {
                return ElectricCharge(Type);
            }
            //Construct primary particle
        	inline Particle(ParticleType aType, cosmo_time aZsource){
                Reset(); Type=aType; fProductionTime.setZ(aZsource) ; Time.setZ(aZsource); SourceParticle = this;
                GenerateId();
            }
    
        	inline Particle& operator=(const Particle& aParticle) {
                memcpy(this, &aParticle, sizeof(Particle)); return *this;
            }
        	inline coord_type beta() const {
                coord_type m=Mass();
                coord_type gamma_1 = m/Energy;
                coord_type beta2 = 1. - gamma_1*gamma_1;
                return sqrt(beta2);
            }
    
            inline void SetParent(const Particle& aParticle){
                GenerateId();
                if(id != aParticle.id){
                    fPrevId = aParticle.id;
                    fProductionTime = Time;
                }
            }
    
        	static double Mass(ParticleType aType);
        	static double ElectricCharge(ParticleType aType);
            void PropagateFreely(cosmo_time dt);
            ParticleType Type;
            double Weight;
            CosmoTime Time;
            double Energy;
            long Ninteractions;//number of interactions in the interaction chain
            coord_type X[3];//comoving coordinates, source location: (0,0,0)
            coord_type Pdir[3];//momentum direction, initial value: (0,0,1)
            unsigned long long id;
            unsigned long long fPrevId;
    
        // TODO: interaction specific attributes should be stored separately in custom structures which can
        // be accessed via pointers stored in interactionData field
            void* interactionData[ParticleCustomDataSize];//used to store interaction specific attributes as pointers
            static int ReserveInteractionDataSlot();//returns index to access and store interaction data or -1 if no space left
    
            const Particle* SourceParticle;
            double Deflection2;//uncorrelated deflection angle squared
            double CorrelatedDeflection;//current value of correlated deflection
            mutable double CorrelatedBpath;// travel distance within B-field coherence length
            CosmoTime fProductionTime; // time when the particle was produced either in source or on the way as secondary from interaction;
            CosmoTime fCascadeProductionTime; // time when primary EM cascade particle was produced by hadron
            double dt; // particle time delay;
            mutable double LastB; //last transverce magnetic field within B-field coherence length
    
            inline double JetOpenningAngle() const
            {
            	return DeflectionAngle()-ObservationAngle();
            }
    
            inline CosmoTime LastDeflectionTime() const
            {
            	return ElectricCharge() ? Time : fProductionTime;
            }
    
            inline double ObservationAngle() const
            {
            	double beta = DeflectionAngle();
            	if(beta==0.)
            		return 0.;
                double sinBeta=sin(beta);
                double pathToLastDeflection = LastDeflectionTime().t()-SourceParticle->Time.t();//distance from the source for the parent electron/positron (valid for small z source and deflection)
                double distanceToSource = Time.t()-SourceParticle->Time.t();// distance between the source and the observer  (valid for small z source)
                return asin(pathToLastDeflection/distanceToSource*sinBeta);// observation angle
            }
    
            inline double DeflectionAngle() const
            {
            	return sqrt(Deflection2 + CorrelatedDeflection*CorrelatedDeflection);
            }
    
            inline double TimeDelay() const
            {
            	if(ElectricCharge())
            		return 0.;//the approximation used below works only for neutral particles ( LastDeflectionTime() > Time.t() )
                double sinBeta=sin(DeflectionAngle());
                double pathToLastDeflection = LastDeflectionTime().t()-SourceParticle->Time.t();//xx - distance from the source for the parent electron/positron (valid for small z source and deflection)
                double distanceToSource = Time.t()-SourceParticle->Time.t();// distance between the source and the observer  (valid for small z source)
                return 2*pathToLastDeflection*(1.0-pathToLastDeflection/distanceToSource)*sinBeta*sinBeta;//  time delay
            }
            inline static const char* Name(ParticleType aType)
            {
                return ParticleNames[aType];
            }
            std::string ToString();
        private:
            static const double MassesMeV[EndLightParticle];
            static const int ElectricCharges[EndLightParticle];
            static const char* ParticleNames[ParticleTypeEOF];
            static int fNextCustomDataIndex;
            static unsigned long long fMaxId;
        };
    }
    #endif	/* PARTICLE_H */