File indexing completed on 2025-10-31 08:21:31
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 
0017 
0018 
0019 
0020 
0021 
0022 
0023 
0024 
0025 
0026 
0027 
0028 
0029 
0030 
0031 
0032 
0033 
0034 
0035 
0036 
0037 
0038 
0039 
0040 
0041 
0042 
0043 
0044 #ifndef CEXMC_CHARGE_EXCHANGE_PRODUCTION_MODEL_HH
0045 #define CEXMC_CHARGE_EXCHANGE_PRODUCTION_MODEL_HH
0046 
0047 #include <G4HadronicInteraction.hh>
0048 #include <G4HadFinalState.hh>
0049 #include <G4HadProjectile.hh>
0050 #include <G4Nucleus.hh>
0051 #include <G4Proton.hh>
0052 #include <G4Neutron.hh>
0053 #include "CexmcProductionModel.hh"
0054 #include "CexmcGenbod.hh"
0055 #include "CexmcReimplementedGenbod.hh"
0056 #include "CexmcException.hh"
0057 
0058 
0059 template  < typename  OutputParticle >
0060 class  CexmcChargeExchangeProductionModel : public G4HadronicInteraction,
0061                                             public CexmcProductionModel
0062 {
0063     public:
0064         CexmcChargeExchangeProductionModel();
0065 
0066         ~CexmcChargeExchangeProductionModel();
0067 
0068     public:
0069         G4HadFinalState *  ApplyYourself( const G4HadProjectile &  projectile,
0070                                           G4Nucleus &  targetNucleus );
0071 
0072     private:
0073         G4double                    nucleusParticleMass;
0074 
0075         CexmcPhaseSpaceGenerator *  phaseSpaceGenerator;
0076 };
0077 
0078 
0079 template  < typename  OutputParticle >
0080 CexmcChargeExchangeProductionModel< OutputParticle >::
0081                                         CexmcChargeExchangeProductionModel() :
0082     G4HadronicInteraction( CexmcChargeExchangeInteractionName ),
0083     CexmcProductionModel( CexmcChargeExchangeProductionModelName ),
0084     nucleusParticleMass( 0 ), phaseSpaceGenerator( NULL )
0085 {
0086     incidentParticle = G4PionMinus::Definition();
0087     nucleusParticle = G4Proton::Definition();
0088     outputParticle = OutputParticle::Definition();
0089     nucleusOutputParticle = G4Neutron::Definition();
0090 
0091     nucleusParticleMass = nucleusParticle->GetPDGMass();
0092 
0093     productionModelData.incidentParticle = incidentParticle;
0094     productionModelData.nucleusParticle = nucleusParticle;
0095     productionModelData.outputParticle = outputParticle;
0096     productionModelData.nucleusOutputParticle = nucleusOutputParticle;
0097 
0098     CexmcPhaseSpaceInVector   inVec;
0099 
0100     inVec.push_back( &productionModelData.incidentParticleSCM );
0101     inVec.push_back( &productionModelData.nucleusParticleSCM );
0102 
0103     CexmcPhaseSpaceOutVector  outVec;
0104 
0105     outVec.push_back( CexmcPhaseSpaceOutVectorElement(
0106                             &productionModelData.outputParticleSCM,
0107                             outputParticle->GetPDGMass() ) );
0108     outVec.push_back( CexmcPhaseSpaceOutVectorElement(
0109                             &productionModelData.nucleusOutputParticleSCM,
0110                             nucleusOutputParticle->GetPDGMass() ) );
0111 
0112 #ifdef CEXMC_USE_GENBOD
0113     phaseSpaceGenerator = new CexmcGenbod;
0114 #else
0115     phaseSpaceGenerator = new CexmcReimplementedGenbod;
0116 #endif
0117 
0118     phaseSpaceGenerator->SetParticles( inVec, outVec );
0119 }
0120 
0121 
0122 template  < typename  OutputParticle >
0123 CexmcChargeExchangeProductionModel< OutputParticle >::
0124                                         ~CexmcChargeExchangeProductionModel()
0125 {
0126     delete phaseSpaceGenerator;
0127 }
0128 
0129 
0130 template  < typename  OutputParticle >
0131 G4HadFinalState *  CexmcChargeExchangeProductionModel< OutputParticle >::
0132                             ApplyYourself( const G4HadProjectile &  projectile,
0133                                            G4Nucleus &  targetNucleus )
0134 {
0135     theParticleChange.Clear();
0136 
0137     G4double           kinEnergy( projectile.GetKineticEnergy() );
0138     G4HadProjectile &  theProjectile( const_cast< G4HadProjectile & >(
0139                                                                 projectile ) );
0140     const G4LorentzRotation &  projToLab(
0141                                     const_cast< const G4LorentzRotation & >(
0142                                             theProjectile.GetTrafoToLab() ) );
0143     productionModelData.incidentParticleLAB = projectile.Get4Momentum();
0144     productionModelData.incidentParticleLAB.transform( projToLab );
0145     productionModelData.nucleusParticleLAB.setPx( 0 );
0146     productionModelData.nucleusParticleLAB.setPy( 0 );
0147     productionModelData.nucleusParticleLAB.setPz( 0 );
0148     productionModelData.nucleusParticleLAB.setE( nucleusParticleMass );
0149 
0150     if ( fermiMotionIsOn )
0151     {
0152         G4ThreeVector  targetNucleusMomentum(
0153                                         targetNucleus.GetFermiMomentum() );
0154         G4double       targetNucleusEnergy(
0155                             std::sqrt( targetNucleusMomentum.mag2() +
0156                                 nucleusParticleMass * nucleusParticleMass ) );
0157         productionModelData.nucleusParticleLAB = G4LorentzVector(
0158                                 targetNucleusMomentum, targetNucleusEnergy );
0159     }
0160     productionModelData.nucleusParticleLAB.transform( projToLab );
0161     G4LorentzVector  lVecSum( productionModelData.incidentParticleLAB +
0162                               productionModelData.nucleusParticleLAB );
0163     G4ThreeVector    boostVec( lVecSum.boostVector() );
0164 
0165     productionModelData.incidentParticleSCM =
0166             productionModelData.incidentParticleLAB;
0167     productionModelData.nucleusParticleSCM =
0168             productionModelData.nucleusParticleLAB;
0169 
0170     productionModelData.incidentParticleSCM.boost( -boostVec );
0171     productionModelData.nucleusParticleSCM.boost( -boostVec );
0172 
0173     triggeredAngularRanges.clear();
0174 
0175     if ( ! phaseSpaceGenerator->CheckKinematics() )
0176     {
0177         theParticleChange.SetEnergyChange( kinEnergy );
0178         theParticleChange.SetMomentumChange(
0179                                     projectile.Get4Momentum().vect().unit());
0180         return &theParticleChange;
0181     }
0182 
0183     do
0184     {
0185         phaseSpaceGenerator->Generate();
0186         G4double  cosTheta( productionModelData.outputParticleSCM.cosTheta() );
0187         for ( CexmcAngularRangeList::iterator  k( angularRanges.begin() );
0188                                                 k != angularRanges.end(); ++k )
0189         {
0190             if ( cosTheta <= k->top && cosTheta > k->bottom )
0191                 triggeredAngularRanges.push_back( CexmcAngularRange(
0192                                                 k->top, k->bottom, k->index ) );
0193         }
0194     } while ( triggeredAngularRanges.empty() );
0195 
0196     productionModelData.outputParticleLAB =
0197             productionModelData.outputParticleSCM;
0198     productionModelData.nucleusOutputParticleLAB =
0199             productionModelData.nucleusOutputParticleSCM;
0200 
0201     productionModelData.outputParticleLAB.boost( boostVec );
0202     productionModelData.nucleusOutputParticleLAB.boost( boostVec );
0203 
0204     theParticleChange.SetStatusChange( stopAndKill );
0205     theParticleChange.SetEnergyChange( 0.0 );
0206 
0207     G4DynamicParticle *  secOutParticle( new G4DynamicParticle(
0208                             outputParticle,
0209                             productionModelData.outputParticleLAB ) );
0210     theParticleChange.AddSecondary( secOutParticle );
0211     G4DynamicParticle *  secNeutron( new G4DynamicParticle(
0212                             nucleusOutputParticle,
0213                             productionModelData.nucleusOutputParticleLAB ) );
0214     theParticleChange.AddSecondary( secNeutron );
0215 
0216     
0217 
0218 
0219     productionModelData.incidentParticle = projectile.GetDefinition();
0220 
0221     return &theParticleChange;
0222 }
0223 
0224 
0225 #endif
0226