From fa8b4123a6b243327cc99a3b60a909a6849dd5d0 Mon Sep 17 00:00:00 2001 From: Adrien Matta <matta@lpccaen.in2p3.fr> Date: Fri, 6 Sep 2024 16:50:55 +0200 Subject: [PATCH] * Inelastic break up now working --- NPSimulation/Process/BeamReaction.cc | 182 +++++++++++++++++++++++++++ NPSimulation/Process/BeamReaction.hh | 4 +- 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/NPSimulation/Process/BeamReaction.cc b/NPSimulation/Process/BeamReaction.cc index b4bd84c6c..3f9bb927c 100644 --- a/NPSimulation/Process/BeamReaction.cc +++ b/NPSimulation/Process/BeamReaction.cc @@ -68,6 +68,8 @@ void NPS::BeamReaction::ReadConfiguration() { if (input.GetAllBlocksWithToken("TwoBodyReaction").size() > 0) m_ReactionType = TwoBody; + if (input.GetAllBlocksWithToken("InelasticBreakup").size() > 0) + m_ReactionType = InelasticBreakup; else if (input.GetAllBlocksWithToken("QFSReaction").size() > 0) m_ReactionType = QFS; else if (input.GetAllBlocksWithToken("PhaseSpace").size() > 0) @@ -89,6 +91,20 @@ void NPS::BeamReaction::ReadConfiguration() { } } + // Inelastic Breakup + if (m_ReactionType == InelasticBreakup) { + m_InelasticBreakup.ReadConfigurationFile(input); + m_BeamName = NPL::ChangeNameToG4Standard(m_InelasticBreakup.GetParticleBeam()->GetName()); + if (m_InelasticBreakup.GetParticleLight()->GetName() != "") { + m_active = true; + m_ReactionConditions = new TReactionConditions(); + AttachReactionConditions(); + if (!RootOutput::getInstance()->GetTree()->FindBranch("ReactionConditions")) + RootOutput::getInstance()->GetTree()->Branch("ReactionConditions", "TReactionConditions", + &m_ReactionConditions); + } + } + // QFS else if (m_ReactionType == QFS) { m_QFS.ReadConfigurationFile(input); @@ -209,6 +225,9 @@ G4bool NPS::BeamReaction::ModelTrigger(const G4FastTrack& fastTrack) { std::cout << "Two body reaction not allowed" << std::endl; } } + else if (m_ReactionType == InelasticBreakup) { + return true; + } else if (m_ReactionType == Fusion) { return true; } @@ -415,6 +434,169 @@ void NPS::BeamReaction::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep) m_ReactionConditions->SetMomentumDirectionZ(momentum_kine3_world.z()); m_ReactionConditions->SetMomentumDirectionZ(momentum_kine4_world.z()); + } // end if TwoBodyReaction + //////////////////////////////////////// + // Inelastic Breakup Reaction Case ///// + //////////////////////////////////////// + if (m_ReactionType == InelasticBreakup) { + + static G4IonTable* IonTable = G4ParticleTable::GetParticleTable()->GetIonTable(); + //////Define the kind of particle to shoot//////// + // Particle Light + G4ParticleDefinition* LightName; + int LightZ = m_InelasticBreakup.GetParticleLight()->GetZ(); + int LightA = m_InelasticBreakup.GetParticleLight()->GetA(); + + if (LightZ == 0 && LightA == 1) { + LightName = G4Neutron::Definition(); + } + else { + LightName = IonTable->GetIon(LightZ, LightA); + } + + // Particle Heavy + G4int HeavyZ = m_InelasticBreakup.GetParticleHeavy()->GetZ(); + G4int HeavyA = m_InelasticBreakup.GetParticleHeavy()->GetA(); + G4ParticleDefinition* HeavyName = IonTable->GetIon(HeavyZ, HeavyA); + + // Particle TargetLike + G4int TargetZ = m_InelasticBreakup.GetParticleTarget()->GetZ(); + G4int TargetA = m_InelasticBreakup.GetParticleTarget()->GetA(); + G4ParticleDefinition* TargetName = IonTable->GetIon(TargetZ, TargetA); + + // Set the Energy of the reaction + m_InelasticBreakup.SetBeamEnergy(reac_energy); + + double Beam_theta = pdirection.theta(); + double Beam_phi = pdirection.phi(); + + /////////////////////////// + ///// Beam Parameters ///// + /////////////////////////// + m_ReactionConditions->SetBeamParticleName(PrimaryTrack->GetParticleDefinition()->GetParticleName()); + + m_ReactionConditions->SetBeamReactionEnergy(reac_energy); + m_ReactionConditions->SetVertexPositionX(worldPosition.x()); + m_ReactionConditions->SetVertexPositionY(worldPosition.y()); + m_ReactionConditions->SetVertexPositionZ(worldPosition.z()); + + G4ThreeVector U(1, 0, 0); + G4ThreeVector V(0, 1, 0); + G4ThreeVector ZZ(0, 0, 1); + m_ReactionConditions->SetBeamEmittanceTheta(PrimaryTrack->GetMomentumDirection().theta() / deg); + m_ReactionConditions->SetBeamEmittancePhi(PrimaryTrack->GetMomentumDirection().phi() / deg); + m_ReactionConditions->SetBeamEmittanceThetaX(PrimaryTrack->GetMomentumDirection().angle(U) / deg); + m_ReactionConditions->SetBeamEmittancePhiY(PrimaryTrack->GetMomentumDirection().angle(V) / deg); + + ////////////////////////////////////////////////////////// + ///// Build rotation matrix to go from the incident ////// + ///// beam frame to the "world" frame ////// + ////////////////////////////////////////////////////////// + + // G4ThreeVector col1(cos(Beam_theta) * cos(Beam_phi), + // cos(Beam_theta) * sin(Beam_phi), + // -sin(Beam_theta)); + // G4ThreeVector col2(-sin(Beam_phi), + // cos(Beam_phi), + // 0); + // G4ThreeVector col3(sin(Beam_theta) * cos(Beam_phi), + // sin(Beam_theta) * sin(Beam_phi), + // cos(Beam_theta)); + // G4RotationMatrix BeamToWorld(col1, col2, col3); + + ///////////////////////////////////////////////////////////////// + ///// Angles for emitted particles following Cross Section ////// + ///// Angles are in the beam frame ////// + ///////////////////////////////////////////////////////////////// + double phi = G4RandFlat::shoot() * 2. * pi; + + ////////////////////////////////////////////////// + ///// Momentum and angles from kinematics ///// + ///// Angles are in the beam frame ///// + ////////////////////////////////////////////////// + // Variable where to store results + double ThetaLight, PhiLight, EnergyLight, ThetaTarget, EnergyTarget, ThetaHeavy, EnergyHeavy; + + // Compute Kinematic using previously defined ThetaCM + m_InelasticBreakup.GenerateEvent(ThetaLight, PhiLight, EnergyLight, ThetaTarget, EnergyTarget, ThetaHeavy, + EnergyHeavy); + // Momentum in beam frame for light particle + G4ThreeVector momentum_kineLight_beam(sin(ThetaLight) * cos(phi), sin(ThetaLight) * sin(phi), cos(ThetaLight)); + // Momentum in World frame //to go from the incident beam frame to the "world" + // frame + G4ThreeVector momentum_kineLight_world = momentum_kineLight_beam; + momentum_kineLight_world.rotate(Beam_theta, + V); // rotation of Beam_theta on Y axis + momentum_kineLight_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Momentum in beam frame for light particle + G4ThreeVector momentum_kineTarget_beam(sin(ThetaTarget) * cos(phi), sin(ThetaTarget) * sin(phi), cos(ThetaTarget)); + // Momentum in World frame //to go from the incident beam frame to the "world" + // frame + G4ThreeVector momentum_kineTarget_world = momentum_kineTarget_beam; + momentum_kineTarget_world.rotate(Beam_theta, + V); // rotation of Beam_theta on Y axis + momentum_kineTarget_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Momentum in beam frame for heavy particle + G4ThreeVector momentum_kineHeavy_beam(sin(ThetaHeavy) * cos(phi + pi), sin(ThetaHeavy) * sin(phi + pi), + cos(ThetaHeavy)); + // Momentum in World frame + G4ThreeVector momentum_kineHeavy_world = momentum_kineHeavy_beam; + momentum_kineHeavy_world.rotate(Beam_theta, + V); // rotation of Beam_theta on Y axis + momentum_kineHeavy_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Emitt secondary + G4DynamicParticle particleLight(LightName, momentum_kineLight_world, EnergyLight); + fastStep.CreateSecondaryTrack(particleLight, localPosition, time); + + G4DynamicParticle particleTarget(LightName, momentum_kineTarget_world, EnergyTarget); + fastStep.CreateSecondaryTrack(particleTarget, localPosition, time); + + G4DynamicParticle particleHeavy(HeavyName, momentum_kineHeavy_world, EnergyHeavy); + fastStep.CreateSecondaryTrack(particleHeavy, localPosition, time); + + /////////////////////////////////////// + ///// Emitted particle Parameters ///// + /////////////////////////////////////// + // Names 3 and 4// + m_ReactionConditions->SetParticleName(LightName->GetParticleName()); + m_ReactionConditions->SetParticleName(TargetName->GetParticleName()); + m_ReactionConditions->SetParticleName(HeavyName->GetParticleName()); + // Angle 3 and 4 // + m_ReactionConditions->SetTheta(ThetaLight / deg); + m_ReactionConditions->SetTheta(ThetaTarget / deg); + m_ReactionConditions->SetTheta(ThetaHeavy / deg); + + m_ReactionConditions->SetPhi(phi / deg); + if ((phi + pi) / deg > 360) + m_ReactionConditions->SetPhi((phi - pi) / deg); + else + m_ReactionConditions->SetPhi((phi + pi) / deg); + + // Energy 3 and 4 // + m_ReactionConditions->SetKineticEnergy(EnergyLight); + m_ReactionConditions->SetKineticEnergy(EnergyTarget); + m_ReactionConditions->SetKineticEnergy(EnergyHeavy); + // ThetaCM and Ex// + m_ReactionConditions->SetThetaCM(m_InelasticBreakup.GetThetaCM() / deg); + m_ReactionConditions->SetExcitationEnergy3(0); + m_ReactionConditions->SetExcitationEnergy3(0); + m_ReactionConditions->SetExcitationEnergy4(0); + // Momuntum X 3 and 4 // + m_ReactionConditions->SetMomentumDirectionX(momentum_kineLight_world.x()); + m_ReactionConditions->SetMomentumDirectionX(momentum_kineTarget_world.x()); + m_ReactionConditions->SetMomentumDirectionX(momentum_kineHeavy_world.x()); + // Momuntum Y 3 and 4 // + m_ReactionConditions->SetMomentumDirectionY(momentum_kineLight_world.y()); + m_ReactionConditions->SetMomentumDirectionY(momentum_kineTarget_world.y()); + m_ReactionConditions->SetMomentumDirectionY(momentum_kineHeavy_world.y()); + // Momuntum Z 3 and 4 // + m_ReactionConditions->SetMomentumDirectionZ(momentum_kineLight_world.z()); + m_ReactionConditions->SetMomentumDirectionZ(momentum_kineTarget_world.z()); + m_ReactionConditions->SetMomentumDirectionZ(momentum_kineHeavy_world.z()); + } // end if TwoBodyReaction // QFS diff --git a/NPSimulation/Process/BeamReaction.hh b/NPSimulation/Process/BeamReaction.hh index 9d1bf2d57..b2f802f30 100644 --- a/NPSimulation/Process/BeamReaction.hh +++ b/NPSimulation/Process/BeamReaction.hh @@ -28,6 +28,7 @@ #include "G4AblaInterface.hh" #include "G4Fragment.hh" #include "G4VFastSimulationModel.hh" +#include "NPInelasticBreakup.h" #include "NPPhaseSpace.h" #include "NPQFS.h" #include "NPReaction.h" @@ -35,7 +36,7 @@ #include "TReactionConditions.h" class G4VPhysicalVolume; namespace NPS { - enum ReactionType { TwoBody, QFS, PhaseSpace, Fusion }; + enum ReactionType { TwoBody, InelasticBreakup, QFS, PhaseSpace, Fusion }; class BeamReaction : public G4VFastSimulationModel { public: @@ -51,6 +52,7 @@ namespace NPS { private: NPL::Reaction m_Reaction; + NPL::InelasticBreakup m_InelasticBreakup; NPL::QFS m_QFS; NPL::PhaseSpace m_PhaseSpace; string m_BeamName; -- GitLab